How do I get a reference to a telerik:GridTemplateColumn from a child control? - asp.net

Simplified code from page:
<%# Page Language="C#" etc... %>
<%# Register src="~/controls/RequiredField.ascx" tagname="rf" tagprefix="custom" %>
<telerik:RadGrid runat="server">
<MasterTableView>
<Columns>
<telerik:GridTemplateColumn DataField="Name" HeaderText="Name" SortExpression="Name">
<ItemTemplate><%#Eval("Name")%></ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="NewName" runat="server" Text='<%#Bind("Name")%>'></asp:TextBox>
<custom:rf runat="server" />
</EditItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
In my control, I want to check if the parent is an EditItemTemplate and then set a property of the telerik:GridTemplateColumn. For example:
public partial class controls_RequiredField : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (this.Parent is Telerik.Web.UI.GridEditFormItem.EditFormTableCell)
{
// how do I get a reference to 'Telerik.Web.UI.GridTemplateColumn' (or any other object that lets me set the header text)
((Telerik.Web.UI.GridTemplateColumn)this.Parent.Parent).EditFormHeaderTextFormat = "{0}:" + RequiredText.Text;
RequiredText.Visible = false;
}
}
}

I don't have the telerik:RadGrid but it is pretty similar to the MS GridView, so I was able to test your issue using asp:GridView (both inherit from CompositeDataBoundControl Class (System.Web.UI.WebControls))
since your custom control is located in the EditItemTemplate your RequiredField control's Page_Load event will not fire until the RadGrid switches to edit mode so you should be able to drop the if (this.Parent is...) check as you'll know the grid is in edit mode.
So with the custom control's page load indicating the grid is in edit mode you can set the HeaderText of the GridTemplateColumn by doing something like:
if (typeof(DataControlFieldCell) == Parent.GetType())
{
((DataControlFieldCell)this.Parent).ContainingField.HeaderText = "Your Custom Heading"; // Or += if appending
}

Well this is the code I'm currently using that works:
protected void Page_Init(object sender, EventArgs e)
{
if (this.Parent is GridEditFormItem.EditFormTableCell)
{
GridEditFormItem.EditFormTableCell parentCell = (GridEditFormItem.EditFormTableCell)this.Parent;
string col = parentCell.ColumnName;
// ridiculous:
Control parentFormItem = this.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent;
if (parentFormItem is GridItem)
{
GridItem gi = (GridItem)parentFormItem;
GridColumn parentColumn = gi.OwnerTableView.Columns.FindByUniqueNameSafe(col);
if (parentColumn != null)
{
parentColumn.EditFormHeaderTextFormat = "{0}:" + RequiredText.Text;
RequiredText.Visible = false;
}
}
}
}
But having to cycle up through all those .Parents makes me uneasy.

Related

Data binding along with the value in ASP.NET

How do you achive something like below in asp.net?
<asp:Label runat="server" Text="The '<%# CustomValue %>' you assigned."/>
This usually depends on where your Label resides. If it is a stond alone control, not nested inside a repeater, you just set your code in code behind:
Label1.Text = $"The {CustomValue} you assigned.";
If the label is nested inside an ItemTemplate in some sort of Repeater control, you can strongly type it to an objects property:
<asp:Repeater runat="server" ID="MyRepeater" ItemType="WebFormsSandbox.Person">
<ItemTemplate>
<li>
<%#: Item.FirstName %> <%#: Item.LastName %>
</li>
</ItemTemplate>
</asp:Repeater>
and the corresponding code behind:
protected void Page_Load(object sender, EventArgs e)
{
MyRepeater.DataSource = Persons();
MyRepeater.DataBind();
}
IEnumerable<Person> Persons()
{
for (int i = 0; i < 10; i++)
{
yield return new Person { Id= i, FirstName = $"Foo{i}", LastName = $"Bar{i}" };
}
}
This would create a list of links, where you then could do anything with it. Whether this would pop up a custom window or does a postback .. up to you.
If you really want to do it that way, write the string inside the server tags.
<asp:Label runat="server" Text='<%# "The " + CustomValue + " you assigned." %>'/>
However if the Label is not inside a GridView, Repeater etc you have to call DataBind manually.
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
You would typically do this in the code behind on page load, unless you were using a datagrid or repeater control. Assign an ID to your control and reference it like so.
<asp:Label runat="server" ID="Label1" />
protected void Page_Load(object sender,EventArgs e)
{
Label1.Text = "Your Value";
}

AspxGridView checkbox checked column value

I am using one aspxGridview where I used checkbox. Now I need when I check any of the row particular column value I should get in server side to complete my business logic.
Below is the gridview used:
<dx:ASPxGridView KeyFieldName="PracticeID" ID="ASPxGrd" runat="server" ClientInstanceName="grid"
ClientIDMode="AutoID" AutoGenerateColumns="false" Width="100%" OnSelectionChanged="ASPxGrd_SelectionChanged">
<Columns>
<dx:GridViewDataColumn VisibleIndex="0" Name="CheckBoxColumn">
<DataItemTemplate>
<dx:ASPxCheckBox ID="ASPxCheckBox1" runat="server" OnCheckedChanged="ASPxCheckBox1_CheckedChanged" AutoPostBack="true">
</dx:ASPxCheckBox>
</DataItemTemplate>
</dx:GridViewDataColumn>
<dx:GridViewDataColumn FieldName="PracticeName" Caption="Description" VisibleIndex="1">
<FooterTemplate>
Total:
</FooterTemplate>
</dx:GridViewDataColumn>
</dx:ASPxGridView>
I have tried to use oncheckedevent in checkbox with auto postback true and used code to get selected row like below:
protected void ASPxCheckBox1_CheckedChanged(object sender, EventArgs e)
{
ASPxGridView grid = sender as ASPxGridView;
string currentMasterKey = Convert.ToString(grid.GetMasterRowKeyValue());
}
but getting null value of grid object.
Need help.
In your example you have used DataItemTemplate, so in that case the sender will be the control which is added in that data template i.e ASPxCheckBox and you are casting it to grid bcoz of that it is getting null.
try out below snippet.
protected void ASPxCheckBox1_CheckedChanged(object sender, EventArgs e)
{
ASPxCheckBox checkBox = sender as ASPxCheckBox;
var grid = (checkBox.NamingContainer as DevExpress.Web.ASPxGridView.GridViewDataItemTemplateContainer).Grid;
string currentMasterKey = Convert.ToString(grid.GetMasterRowKeyValue());
}
I found this answer before and it's working fine like below:
for (int i = 0; i < ASPxGrd.VisibleRowCount; i++)
{
ASPxCheckBox chk = ASPxGrd.FindRowCellTemplateControl(i, null, "ASPxCheckBox1") as ASPxCheckBox;
if (chk.Checked)
{
if (i == 0)
{
practiceName = ASPxGrd.GetRowValues(i, "PracticeName").ToString();
}
}
}
using this code i am able to get selected checkbox column value.

Radio Button inside grid view control not firing oncheckedchanged event

I have following code in my application I have a gridview control insde my grid view I have radio button defined as templetefield.
<asp:View ID="View3" runat="server">
<script type = "text/javascript">
function RadioCheck(rb) {
var gv = document.getElementById("<%=grdAllPartsRequestList.ClientID%>");
var rbs = gv.getElementsByTagName("input");
var row = rb.parentNode.parentNode;
for (var i = 0; i < rbs.length; i++) {
if (rbs[i].type == "radio") {
if (rbs[i].checked && rbs[i] != rb) {
rbs[i].checked = false;
break;
}
}
}
}
</script>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton ID="rbSelected" runat="server" AutoPostBack="True"
oncheckedchanged="rbSelected_CheckedChanged" GroupName="RequestSelection" onclick="RadioCheck(this);" />
<asp:HiddenField ID="HiddenField1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</<asp:View>
Code Behind .CS
protected void rbSelected_CheckedChanged(object sender, EventArgs e)
{
}
Now my problem is upon running my page when I click the radio button the Event doesn't fire. oncheckedchanged is not firing.
Surprisingly The same functionality works fine in another page with in the grid view.
I have searched the web for this answers. But so far nothing worked out. I have Update Panel in my Master Page.. I have tried to play with UpdateMode="Always" and ChildrenAsTriggers="true" but so far nothing worked out please help!
Try this,
void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
Radiobutton rb = e.Row.FindControl("rbSelected") as Radiobutton;
rb.oncheckedchanged += this.rbSelected_CheckedChanged;
}
}
The event will be added to the radiobutton on rowdatabound event of GridView...
Hope this helps you...

invalid postback event instead of dropdown to datagrid

I faced with funny situation. I created a page which is having some value, I set these value and control my post back event also. The problem is happening when I change a component index(ex reselect a combobox which is not inside my datagrid) then I dont know why without my page call the Page_Load it goes to create a new row in grid function and all of my parameter are null! I am just receiving null exception.
So in other word I try to explain the situation:
when I load my page I am initializing some parameter. then everything is working fine. in my page when I change selected item of my combo box, page suppose to go and run function related to that combo box, and call page_load, but it is not going there and it goes to rowcreated function.
I am trying to illustrate part of my page.
Please help me because I am not receiving any error except null exception and it triger wrong even which seems so complicated for me.
public partial class W_CM_FRM_02 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack && !loginFail)
return;
InitializeItems();
}
}
private void InitializeItems()
{
cols = new string[] { "v_classification_code", "v_classification_name" };
arrlstCMMM_CLASSIFICATION = (ArrayList)db.Select(cols, "CMMM_CLASSIFICATION", "v_classification_code <> 'N'", " ORDER BY v_classification_name");
}
}
protected void DGV_RFA_DETAILS_RowCreated(object sender, GridViewRowEventArgs e)
{
//db = (Database)Session["oCon"];
foreach (DataRow dr in arrlstCMMM_CLASSIFICATION)
((DropDownList)DGV_RFA_DETAILS.Rows[index].Cells[4].FindControl("OV_RFA_CLASSIFICATION")).Items.Add(new ListItem(dr["v_classification_name"].ToString(), dr["v_classification_code"].ToString()));
}
protected void V_CUSTOMER_SelectedIndexChanged(object sender, EventArgs e)
{
if (V_CUSTOMER.SelectedValue == "xxx" || V_CUSTOMER.SelectedValue == "ddd")
V_IMPACTED_FUNCTIONS.Enabled = true;
}
}
my form:
<%# Page Language="C#" MasterPageFile="~/MasterPage.master"
AutoEventWireup="true" CodeFile="W_CM_FRM_02.aspx.cs"
Inherits="W_CM_FRM_02" Title="W_CM_FRM_02" enableeventvalidation="false" EnableViewState="true"%>
<td>Project name*</td>
<td><asp:DropDownList ID="V_CUSTOMER" runat="server" AutoPostBack="True"
onselectedindexchanged="V_CUSTOMER_SelectedIndexChanged" /></td>
<td colspan = "8">
<asp:GridView ID="DGV_RFA_DETAILS" runat="server" ShowFooter="True" AutoGenerateColumns="False"
CellPadding="1" ForeColor="#333333" GridLines="None" OnRowDeleting="grvRFADetails_RowDeleting"
Width="100%" Style="text-align: left"
onrowcreated="DGV_RFA_DETAILS_RowCreated">
<RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
<Columns>
<asp:BoundField DataField="ON_RowNumber" HeaderText="SNo" />
<asp:TemplateField HeaderText="RFA/RAD/Ticket No*">
<ItemTemplate>
<asp:TextBox ID="OV_RFA_NO" runat="server" Width="120"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
Hi remove enableeventvalidation="false" EnableViewState="true" from your page directive.

Put focus back on a gridview's selected row after postback

Is it possible to put focus back on a gridview row after that a selection of the row generates a postback?
I'm trying to add an onkeydown handler on the gridview rows in order to use the keyboard for navigation. My problem, I believe, is that after the first postback, the selected cell loses focus, and so the next key stroke is not caught by the cell.
I have the following code
The grid view
<asp:GridView runat="server" ID="gdvPersons" AutoGenerateColumns="false"
onrowcreated="gdvPersons_RowCreated" onselectedindexchanged="gdvPersons_SelectedIndexChanged">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<%# ((GridviewFocus.Person) Container.DataItem).Name %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Age">
<ItemTemplate>
<%# ((GridviewFocus.Person) Container.DataItem).Age %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The Code behind
protected void Page_Load(object sender, EventArgs e)
{
var persons = new List<Person> {new Person() {Name = "Fikre", Age = 24},
new Person() {Name = "Mike", Age = 29},
new Person() {Name = "Mark", Age = 35}};
gdvPersons.DataSource = persons;
gdvPersons.DataBind();
}
protected void gdvPersons_RowCreated(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
e.Row.Attributes.Add("onkeydown", ClientScript.GetPostBackEventReference((Control)sender, "Select$" + e.Row.DataItemIndex));
}
protected void gdvPersons_SelectedIndexChanged(object sender, EventArgs e)
{
gdvPersons.SelectedRow.Focus();
}
On your onkeydown script code copy the id of the cell to a hidden input field.
<input type="text" id="gridviewcell_id" onkeydown="lastcell.value = this.id" />
<input type="hidden" id="lastcell" runat="server" />
the example above is plain html, and you would have to add the proper onkeydown code to your gridview.
In your postback (for example onclick) event handler code you can retrieve the id from the hidden fields value property and register javascript to execute once the page is refreshed. If you have a button which is clicked which performs the postback you could do something like this:
protected void MyButton_Click(object sender, EventArgs e)
{
string id = lastcell.Value;
string script = "var ctrl = document.getElementById('" + lastcell.Value + "');";
script += "ctrl.focus();";
ClientScript.RegisterClientScriptBlock(this.GetType(),
"focusScript", script, true);
}
This should make your page execute the following script once it's loaded, and the control should retrive focus:
var ctrl = document.getElementById("yourid");
ctrl.focus();
Add MaintainScrollPositionOnPostBack="true" in the #Page directive in your .aspx file or add it to system.web/pages section in web.config
<system.web>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" maintainScrollPositionOnPostBack="true"/>
</system.web>
This works also when navigating to previous page with large table e.g.
When Web pages are posted back to the server, the user is returned to the top of the page. On long Web pages, this means that the user has to scroll the page back to the last position on the page.
Documentation

Resources