aspnet-403575-common-concepts-access-controls-in-templates-on-the-server.md
The techniques below allow you to access controls placed within complex controls.
Use a complex control’s FindControl… methods (for instance, the Control.FindControl and FindEditFormTemplateControl(String) methods) to access a child control by its ID. These methods iterate through controls in the current hierarchy to find the target control.
The FindControl… methods only succeed if a child control with the specified ID exists in the current hierarchy.
Handle the following events to access a child control when it is initialized or loaded:
The Init event fires when the control is initialized and before it loads the view state (including the post data).
The Load event fires when the control is completely loaded with the applied client state.
The event handler’s sender parameter allows you to access and manipulate the control directly.
In the event handler, use a child control’s NamingContainer property to access its parent container. Then you can get the container’s information (for instance, a key value (container.KeyValue), bound data item (container.DataItem), and so on).
Note that if you bind a control to data, use the Init event handler.
In this example, the EditForm template contains two text boxes:
The txtName text box contains the CategoryName field value.
The txtDesc text box contains the Description field value.
The code below handles a text box’s Init event to assign text to the editor.
<dx:ASPxGridView ID="grid" runat="server"...>
<!--...-->
<Columns>
<!--...-->
</Columns>
<Templates>
<EditForm>
<!--...-->
<dx:ASPxPageControl...>
<ContentCollection>
<dx:ContentControl runat="server">
<dx:ASPxTextBox ID="txtName" runat="server" OnInit="txtName_Init" />
<dx:ASPxTextBox ID="txtDesc" runat="server" OnInit="txtDesc_Init" />
</dx:ContentControl>
</ContentCollection>
</dx:ASPxPageControl>
</EditForm>
</Templates>
</dx:ASPxGridView>
The following code uses the NamingContainer property to access a text box’s parent container of the GridViewEditFormTemplateContainer type:
protected void txtName_Init(object sender, EventArgs e){
txtName = (ASPxTextBox)sender;
GridViewEditFormTemplateContainer container = txtName.NamingContainer as GridViewEditFormTemplateContainer;
if (!container.Grid.IsNewRowEditing)
txtName.Text = DataBinder.Eval(container.DataItem, "CategoryName").ToString();
}
protected void txtDesc_Init(object sender, EventArgs e){
txtDesc = (ASPxTextBox)sender;
GridViewEditFormTemplateContainer container = txtDesc.NamingContainer as GridViewEditFormTemplateContainer;
if (!container.Grid.IsNewRowEditing)
txtDesc.Text = DataBinder.Eval(container.DataItem, "Description").ToString();
}
protected void grid_RowUpdating(object sender, DevExpress.Web.Data.ASPxDataUpdatingEventArgs e) {
e.NewValues["CategoryName"] = txtName.Text;
e.NewValues["Description"] = txtDesc.Text;
}
Protected Sub txtName_Init(ByVal sender As Object, ByVal e As EventArgs)
txtName = CType(sender, ASPxTextBox)
Dim container As GridViewEditFormTemplateContainer = TryCast(txtName.NamingContainer, GridViewEditFormTemplateContainer)
If (Not container.Grid.IsNewRowEditing) Then
txtName.Text = DataBinder.Eval(container.DataItem, "CategoryName").ToString()
End If
End Sub
Protected Sub txtDesc_Init(ByVal sender As Object, ByVal e As EventArgs)
txtDesc = CType(sender, ASPxTextBox)
Dim container As GridViewEditFormTemplateContainer = TryCast(txtDesc.NamingContainer, GridViewEditFormTemplateContainer)
If (Not container.Grid.IsNewRowEditing) Then
txtDesc.Text = DataBinder.Eval(container.DataItem, "Description").ToString()
End If
End Sub
Protected Sub grid_RowUpdating(ByVal sender As Object, ByVal e As DevExpress.Web.Data.ASPxDataUpdatingEventArgs)
e.NewValues("CategoryName") = txtName.Text
e.NewValues("Description") = txtDesc.Text
End Sub
In the following example, the grid contains cell templates for two columns. The first column displays combo boxes and the second column displays text boxes in their cells. A text box’s text changes when a user selects an item from the combo box’s drop-down list.
<dx:GridViewDataTextColumn ...>
<DataItemTemplate>
<dx:ASPxComboBox ID="cb" runat="server" OnInit="cb_Init">
</dx:ASPxComboBox>
</DataItemTemplate>
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn ...>
<DataItemTemplate>
<dx:ASPxTextBox ID="txt" runat="server" OnInit="txt_Init">
</dx:ASPxTextBox>
</DataItemTemplate>
</dx:GridViewDataTextColumn>
The text box’s Init event handler specifies the editor’s ClientInstanceName property to allow access to the text box on the client side. In this example, a ClientInstanceName value is a concatenation of the “txt” string and the row visible index (for instance, in the first row, the text box’s ClientInstanceName value is txt0).
The following code uses the NamingContainer property to access the text box’s container of the GridViewDataItemTemplateContainer type:
protected void txt_Init(object sender, EventArgs e){
ASPxTextBox txt = sender as ASPxTextBox;
GridViewDataItemTemplateContainer container = txt.NamingContainer as GridViewDataItemTemplateContainer;
// Assigns a unique client-side identifier to the control.
txt.ClientInstanceName = String.Format("txt{0}", container.VisibleIndex);
}
Protected Sub txt_Init(ByVal sender As Object, ByVal e As EventArgs)
Dim txt As ASPxTextBox = TryCast(sender, ASPxTextBox)
Dim container As GridViewDataItemTemplateContainer = TryCast(txt.NamingContainer, GridViewDataItemTemplateContainer)
' Assigns a unique client-side identifier to the control.
txt.ClientInstanceName = String.Format("txt{0}", container.VisibleIndex)
End Sub
The combo box’s Init event handler performs the following actions:
Assigns a client-side identifier to the combo box.
Specifies the client-side SelectedIndexChanged event handler.
Populates the control’s item collection with data.
protected void cb_Init(object sender, EventArgs e){
ASPxComboBox cb = sender as ASPxComboBox;
GridViewDataItemTemplateContainer container = cb.NamingContainer as GridViewDataItemTemplateContainer;
// Assigns a unique client-side identifier to the control.
cb.ClientInstanceName = String.Format("cb{0}", container.VisibleIndex);
// Handles the "SelectedIndexChanged" event.
cb.ClientSideEvents.SelectedIndexChanged = String.Format("function (s, e) {{ OnSelectedIndexChanged(s, e, txt{0}); }}", container.VisibleIndex);
// Populates the item collection with data.
cb.ValueType = typeof(System.Int32);
cb.Items.Add("Text1", 1);
cb.Items.Add("Text2", 2);
cb.Items.Add("Text3", 3);
cb.Items.Add("Text4", 4);
cb.Items.Add("Text5", 5);
}
Protected Sub cb_Init(ByVal sender As Object, ByVal e As EventArgs)
Dim cb As ASPxComboBox = TryCast(sender, ASPxComboBox)
Dim container As GridViewDataItemTemplateContainer = TryCast(cb.NamingContainer, GridViewDataItemTemplateContainer)
' Assigns a unique client-side identifier to the control.
cb.ClientInstanceName = String.Format("cb{0}", container.VisibleIndex)
' Handles the "SelectedIndexChanged" event.
cb.ClientSideEvents.SelectedIndexChanged = String.Format("function (s, e) {{ OnSelectedIndexChanged(s, e, txt{0}); }}", container.VisibleIndex)
' Populates the item collection with data.
cb.ValueType = GetType(System.Int32)
cb.Items.Add("Text1", 1)
cb.Items.Add("Text2", 2)
cb.Items.Add("Text3", 3)
cb.Items.Add("Text4", 4)
cb.Items.Add("Text5", 5)
End Sub
The SelectedIndexChanged event handler calls the OnSelectedIndexChanged function. This function gets a text box’s ClientInstanceName value as the txt parameter to assign the combo box’s selected value to text of the corresponding ASPxTextBox.
function OnSelectedIndexChanged (s, e, txt){
var text = s.GetText();
txt.SetText(text);
}
In this example, a column cell template contains the ASPxLabel control.
<dx:ASPxGridView ID="grid" ClientInstanceName="grid" runat="server" DataSourceID="SalesPersonsDataSource"
KeyFieldName="OrderID" AutoGenerateColumns="False" >
<Columns>
<dx:GridViewDataTextColumn FieldName="ProductName" />
<dx:GridViewDataTextColumn FieldName="CategoryName" />
<dx:GridViewDataDateColumn FieldName="OrderDate" />
<dx:GridViewDataTextColumn>
<DataItemTemplate>
<dx:ASPxLabel ID="MyLabel" runat="server" Text='<%# Eval("UnitPrice", "{0:c}") %>' OnInit="Label_Init"></dx:ASPxLabel>
</DataItemTemplate>
</dx:GridViewDataTextColumn>
</Columns>
</dx:ASPxGridView>
<ef:EntityDataSource runat="server" ID="SalesPersonsDataSource" ContextTypeName="DevExpress.Web.Demos.NorthwindContext" EntitySetName="SalesPersons"/>
The code below handles the Init event to specify a label’s forecolor according to its value. To get this value, the handler’s code accesses the label’s parent container of the GridViewDataItemTemplateContainer type:
protected void Label_Init(object sender, EventArgs e)
{
ASPxLabel lb = sender as ASPxLabel;
GridViewDataItemTemplateContainer container = lb.NamingContainer as GridViewDataItemTemplateContainer;
decimal value = Convert.ToDecimal(container.Grid.GetRowValues(container.VisibleIndex, "UnitPrice"));
if (value > 10) {
lb.ForeColor = System.Drawing.Color.Green;
}
else {
lb.ForeColor = System.Drawing.Color.Red;
}
}
Protected Sub Lable_Init(ByVal sender As Object, ByVal e As EventArgs)
Dim lb As ASPxLabel = TryCast(sender, ASPxLabel)
Dim container As GridViewDataItemTemplateContainer = TryCast(lb.NamingContainer, GridViewDataItemTemplateContainer)
Dim value As Decimal = Convert.ToDecimal(container.Grid.GetRowValues(container.VisibleIndex, "UnitPrice"))
If value > 10 Then
lb.ForeColor = System.Drawing.Color.Green
Else
lb.ForeColor = System.Drawing.Color.Red
End If
End Sub
See the following topic to learn more about template containers: General information about Template containers.