1. UserControls as Edit Form
You have two options with regard to the implementation of the web user control, depending on the desired mode of exchanging data between Telerik RadGrid and the UserControl instances:
- binding directly to RadGrid's Item
- declaring and binding to DataItem property of the UserControl
Binding to RadGrid Item
In order to access data from the object the edit form is binding to, the binding expression used in the UserControl should be implemented in a slightly different than the traditional way. The problem is that the controls are inside UserControl. And the UserControl is in turn a binding container. You have to bind to GridEditFormItem instead of UserControl. That is why the binding expression should be designed to calculate properties for the parent's binding container.
Here is an example of declaration of a TextBox server control that should be bound to the Region property of the DataItem in RadGrid:
| ASPX/ASCX |
Copy Code |
|
<asp:TextBox id="TextBox1" runat="server" Text='<%# DataBinder.Eval( Container, "Parent.BindingContainer.DataItem.Region") %>' |
Using the DataItem Property
If using this kind of expression seems uncomfortable in some way, you have another option. Your user control should implement a property with name DataItem. This property should be public and assignable from the type of the object that constructs the datasource for RadGrid.
For example, if you bind to a DataSet, the DataItem can be declared as:
| C# |
Copy Code |
|
private object _dataItem = null;
public object DataItem { get { return this._dataItem; } set { this._dataItem = value; } } |
| VB.NET |
Copy Code |
|
private _dataItem As Object = Nothing
Public Property DataItem As Object Get Return Me._dataItem End Get Set (ByVal value As Object) Me._dataItem = value End Set End Property
|
Note that DataItem should be declared as of type object. After loading the UserControl, RadGrid will try to assign the value of the DataItem property. This allows you to write in the user control code an expression binding the text of a TextBox control to the Country property of the datasource item:
| ASPX/ASCX |
Copy Code |
|
<asp:TextBox id="TextBox1" runat="server" Text='<%# DataBinder.Eval( Container, "DataItem.Country" ) %>'> </asp:TextBox> |
and the same TextBox using ASP.NET 2.0 syntax
| ASPX/ASCX |
Copy Code |
|
<asp:TextBox id="TextBox1" runat="server" Text='<%# Eval( "Country" ) %>'> </asp:TextBox> |
Referring UserControl in EditForms
In some scenarios you may need to have a reference to the UserControl when the Update button is pressed. Having in mind that the UserControl is a Container placed in a Container (EditFormCell), you should refer to the control this way:
| C# |
Copy Code |
|
UserControl MyUserControl = editFormItem.FindControl(GridEditFormItem.EditFormUserControlID) as UserControl; |
| VB.NET |
Copy Code |
|
Dim MyUserControl As UserControl = CType(editFormItem.FindControl(GridEditFormItem.EditFormUserControlID), UserControl)
|
Accessing the edited grid item from the user controlWhen Telerik RadGrid loads the UserControl Edit Form, the UserControl has full access to the properties of the grid item it is loaded in:
Me.Parent.NamingContainer would reference the currently edited item:
| C# |
Copy Code |
|
GridEditableItem editedItem = this.Parent.NamingContainer |
| VB.NET |
Copy Code |
|
Dim editedItem As GridEditableItem = Me.Parent.NamingContainer
|
Then you have access to all properties of the item - cell text values, DataItem object (available in DataBinding event handler), etc.
Accessing the page
You can access the Page which holds the grid instance from within the user control. In the example below Page is a reference to the page object:
| C# |
Copy Code |
|
MyPageClassName myPage = this.Page |
| VB.NET |
Copy Code |
|
Dim myPage as MyPageClassName = Me.Page
|
Now you can reference all properties of the actual Page.
Binding selected values for MS DropDownLists when having user control custom edit form
In order to select the proper item in dropdown editor (part of user control custom edit form) when grid item is switched in edit mode, you can wire the DataBinding event of the user control. Then inside its handler you can bind the dropdown list and set its SelectedIndex accordingly.
Below is the code used in the user control edit form from online demo of the product:
| VB.NET |
Copy Code |
|
Private Sub EmployeeDetails_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DataBinding
Dim tocs As New ArrayList(New String() {"Dr.", "Mr.", "Mrs.", "Ms."}) ddlTOC.DataSource = tocs ddlTOC.DataBind()
ddlTOC.SelectedIndex = tocs.IndexOf(DataBinder.Eval(DataItem, "TitleOfCourtesy").ToString()) ddlTOC.DataSource = Nothing
End Sub |
| C# |
Copy Code |
|
private void EmployeeDetails_DataBinding(object sender, System.EventArgs e) { String [] tocs = new string[] {"Dr.", "Mr.", "Mrs.", "Ms."}; ddlTOC.DataSource = tocs; ddlTOC.DataBind(); ddlTOC.SelectedIndex = tocs.IndexOf(DataBinder.Eval(DataItem, "TitleOfCourtesy").ToString()); ddlTOC.DataSource = null; } |
 |
Note: An important detail is to assign empty data source for the combo in order to prevent binding it again at a later stage (when the rest of the edited item content is bound). The same conventions stand for nested user controls inside WebUserControl custom edit form or other controls such as listboxes, radiobutton lists, checkbox lists, etc. |
Setting properties without the usage of binding expressions
You can hook the ItemDataBound event of the grid to access the controls/properties of the user control edit form. In the respective handler, you should check whether the type of item is GridEditFormItem and also whether the item is in edit mode. Then you can locate the user control inside the GridEditFormItem and make the modifications you wish. Here is an example which will set text for TextBox with ID = "TextBox1" which resides inside the user control:
| C# |
Copy Code |
|
private void RadGrid1_ItemDataBound(object sender, Telerik.WebControls.GridItemEventArgs e) { if(e.Item is GridEditFormItem && e.Item.IsInEditMode) { UserControl MyUserControl = e.Item.FindControl (GridEditFormItem.EditFormUserControlID) as UserControl; TextBox box = (TextBox)MyUserControl.FindControl("TextBox1"); box.Text = "default text"; } } |
| VB.NET |
Copy Code |
|
Private Sub RadGrid1_ItemDataBound(ByVal sender As Object, ByVal e As Telerik.WebControls.GridItemEventArgs) Handles RadGrid1.ItemDataBound If (TypeOf e.Item Is GridEditFormItem AndAlso e.Item.IsInEditMode) Then Dim MyUserControl As UserControl = CType(e.Item.FindControl(GridEditFormItem.EditFormUserControlID),UserControl) Dim box As TextBox = CType(MyUserControl.FindControl("TextBox1"),TextBox) box.Text = "default text" End If End Sub
|
2. FormTemplate
Binding to RadGrid Item
In order to access data from the object to which the edit form is binding to, you can use the standard binding expression syntax for .NET 1.x:
| ASPX/ASCX |
Copy Code |
|
<editformsettings editformtype="Template">
<editcolumn uniquename="EditCommandColumn1"></editcolumn>
<formtemplate> ------------------------ <asp:textbox id="TextBox7" runat="server" text='<%# DataBinder.Eval( Container, "DataItem.Country" ) %>'>
</asp:textbox>
-------------------------
</formtemplate>
<editformsettings>
Or the newly introduced Bind() syntax available under ASP.NET 2.0:
<editformsettings editformtype="Template">
<editcolumn uniquename="EditCommandColumn1"></editcolumn>
<formtemplate> ------------------------ <asp:textbox id="TextBox7" runat="server" text='<%# Bind(“%>'>
</asp:textbox>
-------------------------
</formtemplate>
<editformsettings> |
Here are two online examples (in C# and VB.NET) which demonstrate this approach:
http://www.telerik.com/demos/aspnet/Grid/Examples/DataEditing/TemplateFormUpdate/DefaultCS.aspx
http://www.telerik.com/demos/aspnet/Grid/Examples/DataEditing/TemplateFormUpdate/DefaultVB.aspx
 |
Note: with the Bind() syntax mentioned above you will be able to extract the updated by the user value from the FormTemplate (without any additional code) and pass it directly for the Automatic update operation through the DataSource control. See also Automatic DataSource operations |
Setting properties without the usage of binding expressions
You can hook the ItemDataBound event of the grid to access the controls/properties of the FormTemplate edit form. In the respective handler, you should check whether the type of item is GridEditFormItem and also whether it is in edit mode. Then you can locate the control inside the GridEditFormItem and make the modifications you wish. Here is an example which will set text for TextBox with ID = "TextBox1" which resides inside the FormTemplate:
| C# |
Copy Code |
|
private void RadGrid1_ItemDataBound(object sender, Telerik.WebControls.GridItemEventArgs e) { if (e.Item Is GridEditFormItem && e.Item.IsInEditMode) { GridEditFormItem editFormItem = e.Item as GridEditFormItem; TextBox box = editFormItem.FindControl("TextBox1") as TextBox; box.Text = "default text"; } } |
| VB.NET |
Copy Code |
|
Private Sub RadGrid1_ItemDataBound(ByVal sender As Object, ByVal e As Telerik.WebControls.GridItemEventArgs) Handles RadGrid1.ItemDataBound If (TypeOf e.Item Is GridEditFormItem AndAlso e.Item.IsInEditMode) Then Dim editFormItem As GridEditFormItem = CType(e.Item, GridEditFormItem) Dim box As TextBox = CType(editFormItem.FindControl("TextBox1"), TextBox) box.Text = "default text" End If End Sub
|
Access to the parent item of the GridEditFormItem (FormTemplate)
| C# |
Copy Code |
|
GridEditableItem parentItem = editFormItem.ParentItem as GridEditableItem; |
| VB.NET |
Copy Code |
|
Dim parentItem as GridEditableItem = CType(editFormItem.ParentItem, GridEditableItem)
|
Then through the parentItem object you will have access to all properties of the item (cell text values or other).
Creating FormTemplate custom edit form programmatically
Basically, you will need to design a class which implements the IBindableTemplate interface and assign an instance of that class to the EditFormSettings.FormTemplate property of the master/detail table. Additionally, you can expose ExtractValues method for that class which to extract the data from the edit form on update/insert operation.
Below are the code snippets of a sample approach:
| C# |
Copy Code |
|
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using Telerik.WebControls; using System.Collections.Specialized; using System.Collections; public partial class Default2 : System.Web.UI.Page { private RadGrid grid1; protected void Page_Init(object sender, EventArgs e) { grid1 = new RadGrid(); grid1.DataSourceID = "SqlDataSource1"; grid1.MasterTableView.EditFormSettings.EditFormType = GridEditFormType.Template; grid1.MasterTableView.EditFormSettings.FormTemplate = new MyEditFormTemplate(); grid1.MasterTableView.Columns.Add(new GridEditCommandColumn()); grid1.MasterTableView.DataKeyNames = new string[] { "ProviderName"}; placeholder1.Controls.Add(grid1); } private void grid1_UpdateCommand(object source, GridCommandEventArgs e) { GridEditableItem ei = ((GridEditableItem)(e.Item)); Hashtable t1 = new Hashtable(); ei.ExtractValues(t1); } public class MyEditFormTemplate : IBindableTemplate { public void InstantiateIn(Control container) { GridEditFormItem item = ((GridEditFormItem)(container.NamingContainer)); Button btn1 = new Button(); btn1.CommandName = "Update"; TextBox tb1 = new TextBox(); tb1.ID = "MyTextBox"; tb1.Text = item.ParentItem.OwnerTableView.DataKeyValues(((GridDataItem)(item.ParentItem)).ItemIndex)["ProviderName"].ToString(); container.Controls.Add(tb1); container.Controls.Add(btn1); } public System.Collections.Specialized.IOrderedDictionary ExtractValues(System.Web.UI.Control container) { OrderedDictionary od = new OrderedDictionary(); od.Add("ProviderName", ((TextBox)(((GridEditFormItem)(container)).FindControl("MyTextBox"))).Text); return od; } } } |
| VB.NET |
Copy Code |
|
Imports System Imports System.Data Imports System.Configuration Imports System.Web Imports System.Web.Security Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.WebControls.WebParts Imports System.Web.UI.HtmlControls Imports Telerik.WebControls Imports System.Collections.Specialized Imports System.Collections Public Partial Class Default2 Inherits System.Web.UI.Page Private grid1 As RadGrid Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) grid1 = New RadGrid() grid1.DataSourceID = "SqlDataSource1" grid1.MasterTableView.EditFormSettings.EditFormType = GridEditFormType.Template grid1.MasterTableView.EditFormSettings.FormTemplate = New MyEditFormTemplate() grid1.MasterTableView.Columns.Add(New GridEditCommandColumn()) grid1.MasterTableView.DataKeyNames = New String() {"ProviderName"} placeholder1.Controls.Add(grid1) End Sub Private Sub grid1_UpdateCommand(ByVal source As Object, ByVal e As GridCommandEventArgs) Dim ei As GridEditableItem = (DirectCast((e.Item), GridEditableItem)) Dim t1 As New Hashtable() ei.ExtractValues(t1) End Sub Public Class MyEditFormTemplate Implements IBindableTemplate Public Sub InstantiateIn(ByVal container As Control) Dim item As GridEditFormItem = (DirectCast((container.NamingContainer), GridEditFormItem)) Dim btn1 As New Button() btn1.CommandName = "Update" Dim tb1 As New TextBox() tb1.ID = "MyTextBox" tb1.Text = item.ParentItem.OwnerTableView.DataKeyValues((DirectCast((item.ParentItem), GridDataItem)).ItemIndex)("ProviderName").ToString() container.Controls.Add(tb1) container.Controls.Add(btn1) End Sub Public Function ExtractValues(ByVal container As System.Web.UI.Control) As System.Collections.Specialized.IOrderedDictionary Dim od As New OrderedDictionary() od.Add("ProviderName", (DirectCast(((DirectCast((container), GridEditFormItem)).FindControl("MyTextBox")), TextBox)).Text) Return od End Function End Class End Class |