Updating Values Using InPlace and EditForms Modes
There are three common techniques for updating a grid row when the user edits it using an inplace editor or edit form:
-
Enable automatic data source operations for the grid: This approach requires no code on your part. For a live example illustrating this approach, see Automatic Operations.
-
Use the table view's ExtractValuesFromItem(dictonaryObject, editedItem) method: For this approach, create an empty dictionary object and pass it as the first parameter of the ExtractValuesFromItem method. Pass the edited item as the second parameter. The ExtractValuesFromItem method fills the dictionary object with key/value pairs where each key is the DataField of an edited field column and the corresponding value is the new data entered by the user.
-
Fetch the data from each edited field individually through the auto-generated column editors: For this approach, you need to iterate through the editable fields of the edited row and modify the grid source on every iteration.
When using the second or third approach, you can refresh the grid content inside an UpdateCommand event handler. The following examples illustrate these techniques. They both use the same grid declaration:
<telerik:RadGrid RenderMode="Lightweight" ID="RadGrid1" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource"
OnUpdateCommand="RadGrid1_UpdateCommand">
<MasterTableView AutoGenerateColumns="False" DataKeyNames="OrderID">
<Columns>
<telerik:GridBoundColumn HeaderText="OrderID" DataField="OrderID" ReadOnly="True"
UniqueName="OrderID" Display="False" />
<telerik:GridBoundColumn HeaderText="EmployeeID" DataField="EmployeeID" UniqueName="EmployeeID" />
<telerik:GridBoundColumn HeaderText="OrderDate" DataField="OrderDate" UniqueName="OrderDate" />
<telerik:GridBoundColumn HeaderText="ShipName" DataField="ShipName" UniqueName="ShipName" />
<telerik:GridEditCommandColumn UniqueName="EditCommandColumn" />
</Columns>
</MasterTableView></telerik:RadGrid><asp:Label ID="Label1" runat="server" />
Both examples also use a ViewState property (named "GridSource") for maintaining the grid's data source, and have the same NeedDataSource event handler:
private DataTable GridSource
{
get
{
Object obj = this.ViewState["_gds"];
if(obj != null)
{
return (DataTable)obj;
}
else
{
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" +
System.Web.HttpContext.Current.Server.MapPath( "~/App_Data/Nwind.mdb"));
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.SelectCommand = new OleDbCommand("SELECT TOP 10 OrderID, EmployeeID, OrderDate, ShipName FROM Orders", conn);
DataTable table = new DataTable();
conn.Open();
try
{
adapter.Fill(table);
}
finally
{
conn.Close();
}
this.ViewState[ "_gds"] = table;
return table;
}
}
}
protected void RadGrid1_NeedDataSource(object source,
Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
RadGrid1.DataSource = this.GridSource;
}
Example 1: Using ExtractValuesFromItem
protected void RadGrid1_UpdateCommand(object source,
Telerik.Web.UI.GridCommandEventArgs e)
{
GridEditableItem editedItem = e.Item as GridEditableItem;
DataTable ordersTable = this.GridSource;
//Locate the changed row in the DataSource
DataRow[] changedRows = ordersTable.Select("OrderID = " +
editedItem.OwnerTableView.DataKeyValues[editedItem.ItemIndex]["OrderID"].ToString());
if (changedRows.Length != 1)
{
this.Label1.Text += "Unable to locate the Order for updating.";
e.Canceled = true;
return;
}
//Update new values
Hashtable newValues = new Hashtable();
e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem);
changedRows[0].BeginEdit();
try
{
foreach (DictionaryEntry entry in newValues)
{
changedRows[0][(string)entry.Key] = entry.Value;
}
changedRows[0].EndEdit();
}
catch (Exception ex)
{
changedRows[0].CancelEdit();
Label1.Text += "Unable to update Orders. Reason: " + ex.Message;
e.Canceled = true;
}
}
Example 2: Using the auto-generated column editors
private void RadGrid1_UpdateCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
{
Label1.Text += " Table to be updated: " + e.Item.OwnerTableView.DataMember + "<br>";
GridEditableItem editedItem = e.Item as GridEditableItem;
GridEditManager editMan = editedItem.EditManager;
foreach( GridColumn column in e.Item.OwnerTableView.RenderColumns )
{
if ( column is IGridEditableColumn )
{
IGridEditableColumn editableCol = (column as IGridEditableColumn);
if ( editableCol.IsEditable )
{
IGridColumnEditor editor = editMan.GetColumnEditor( editableCol );
string editorText = "unknown";
object editorValue = null;
if ( editor is GridTextColumnEditor )
{
editorText = (editor as GridTextColumnEditor).Text;
editorValue = (editor as GridTextColumnEditor).Text;
}
if ( editor is GridBoolColumnEditor )
{
editorText = (editor as GridBoolColumnEditor).Value.ToString();
editorValue = (editor as GridBoolColumnEditor).Value;
}
if ( editor is GridDropDownColumnEditor )
{
editorText = (editor as GridDropDownColumnEditor).SelectedText + "; " +
(editor as GridDropDownColumnEditor).SelectedValue;
editorValue = (editor as GridDropDownColumnEditor).SelectedValue;
}
try
{
DataRow[] changedRows = this.GridSource.Select( "OrderID = " + editedItem.OwnerTableView.DataKeyValues[editedItem.ItemIndex]["OrderID"].ToString());
changedRows[0][column.UniqueName] = editorValue;
this.GridSource.AcceptChanges();
}
catch(Exception ex)
{
Label1.Text = "<strong>Unable to set value of column '" + column.UniqueName + "'</strong> - " + ex.Message;
e.Canceled = true;
break;
}
}
}
}
}
Extracting data from a Template Column
For GridTemplateColumn instances, the ExtractValues()
method will provide data in case there is a <%#Bind("someColumn") %>
expression in the EditItemTemplate
or InsertItemTemplate
. The key in the hashtable will be the field from the binding expression.
For example, the columns below will populate the hash table with data for the "someField" and "moreData" respectively, even though both have the same DataField
setting.
<telerik:GridTemplateColumn HeaderText="template column" DataField="someColumn" UniqueName="myTemplateColumn">
<ItemTemplate>
<%#Eval("someColumn") %>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="textbox1" Text='<%#Bind("someColumn") %>' />
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox runat="server" ID="textbox1" Text='<%#Bind("someColumn") %>' />
</InsertItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderText="second template column" DataField="someColumn" UniqueName="myTemplateColumn2">
<ItemTemplate>
<%#Eval("moreData") %>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="textbox2" Text='<%#Bind("moreData") %>' />
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox runat="server" ID="textbox2" Text='<%#Bind("moreData") %>' />
</InsertItemTemplate>
</telerik:GridTemplateColumn>
For more complex scenarios or when you cannot use binding expressions, you need to use .FindControl()
to access the custom controls and extract data: Accessing Controls in Template Column.