I have all my columns built runtime using TemplateColumns. Now I want to implement in-place editors and I can't do EditorItemTemplate. Forum search refers 2-3 years old solutions which I cannot implement. Can you please help?
Thank you.
17 Answers, 1 is accepted

When programmatically creating template columns, your entire RadGrid should be programmatically created in the Init phase of the page. You can refer to the RadGrid Programmatic Creation help topic (particularly to section "Creating template columns programmatically"). If your RadGrid definition meets this condition, then defining an EditItemTemplate in your columns is no different than defining the ItemTemplate. Please refer to the Creating Web Server Control Templates Programmatically topic in the MSDN for more information on how to dynamically instantiate templates.
Greetings,
Veli
the Telerik team
Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.

Yes, I know how to add template to template columns. But I'm not sure there is no difference between ItemTemplate and EditItemTemplate. This is what I did for EditItemTemplate:
public class EditItemTemplateBase : ITemplate { protected ZSheetItem Item { get; private set; } protected ZSheetView ZSheet { get; private set; } public EditItemTemplateBase(ZSheetItem item, ZSheetView zsheet) { Item = item; ZSheet = zsheet; } #region Implementation of ITemplate public void InstantiateIn(Control container) { TextBox tb1 = new TextBox { ID = "tb_" + Item.f_name, }; tb1.DataBinding += tb1_DataBinding; container.Controls.Add(tb1); } void tb1_DataBinding(object sender, EventArgs e) { TextBox tb = (TextBox) sender; DataRowView drv = GetDataRowView(tb); tb.Text = drv[Item.user_name].ToString(); } #endregion protected DataRowView GetDataRowView(WebControl control) { GridDataItem dataItem = control.NamingContainer as GridDataItem; if (dataItem == null) return null; return (DataRowView)dataItem.DataItem; } }and I'm getting a NullReferenceException which I cannot locate. Is there something I have missed in the code above?
Thank you.
Can you show us the stack trace of the exception you are getting?
In the mean time, try implementing the IBindableTemplate interface for your column's EditItemTemplate. The IBindableTemplate defines an extra method (ExtractValues) which is used for extracting edited values with two-way databinding. Let me know if you are getting the exception in this case.
Greetings,
Veli
the Telerik team
Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.

I tried to implement IBindableTemplate and now I don't get any errors. But I cannot save update data because ItemUpdate event won't ever fire. I programmatically create columns and have EnableColulmnViewState = false. Also, I have datasource created runtime and bound to grid in NeedDataSource event handler. Do you have any ideas of what could be wrong?
Thank you.
Veli
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

I'm not sure if I can post the whole source code but I will try to show you core things.
This is what I put in Page_Init handler:
Columns.Clear(); foreach (GridColumn column in _columnBuilder.BuildColumns(_zsheet, _zTable, _dataSourceProvider)) { Columns.Add(column); }
This is where I build columns:
public List<GridColumn> BuildColumns(ZSheetView zsheet, ZSheetTable table, ZSheetDataSourceProvider dataSourceProvider) { _table = table; _zsheet = zsheet; _columns = new List<GridColumn>(); SortColumns(); foreach (var item in SortedColumns) { TemplateColumnBase column; switch (item.Item2.ItemType) { case ZSheetItemDataType.CheckBox: column = new CheckBoxColumn(item.Item2, zsheet, parser.Appearances, itemAnnotations, correctionRows); break; case ZSheetItemDataType.HyperLink: column = new HyperlinkColumn(item.Item2, zsheet, parser.Appearances, itemAnnotations, correctionRows); break; case ZSheetItemDataType.RefBook: column = new ReferenceColumn(item.Item2, zsheet, parser.Appearances, itemAnnotations, correctionRows); break; case ZSheetItemDataType.Image: column = new ImageColumn(item.Item2, zsheet, parser.Appearances, itemAnnotations, correctionRows); break; case ZSheetItemDataType.File: column = new FileColumn(item.Item2, zsheet, parser.Appearances, itemAnnotations, correctionRows); break; case ZSheetItemDataType.Appearance: column = new AppearanceColumn(item.Item2, zsheet, parser.Appearances, itemAnnotations, correctionRows); break; case ZSheetItemDataType.RtfText: column = new RtfColumn(item.Item2, zsheet, parser.Appearances, itemAnnotations, correctionRows); break; default: column = new TemplateColumnBase(item.Item2, zsheet, parser.Appearances, itemAnnotations, correctionRows); if (item.Item2.f_name == "id") column.Display = false; break; } column.UniqueName = item.Item2.f_name; column.DataField = item.Item2.user_name; column.CreateTemplates(); _columns.Add(column);}
All those columns are inherited from GridTemplateColumn.
And this is where templates created inside template column:
internal virtual void CreateTemplates() { SortExpression = Item.user_name; ItemTemplate = new ItemTemplateBase(Item, ZSheet, Appearances, Styles, Annotations, CorrectionRows); HeaderTemplate = new HeaderTemplate(Item, Styles); EditItemTemplate = new EditItemTemplateBase(Item, ZSheet); }And this is my EditTemplateBase class:
internal class EditItemTemplateBase : IBindableTemplate { protected ZSheetItem Item { get; private set; } protected ZSheetView ZSheet { get; private set; } protected WebControl EditorControl { get; private set; } public EditItemTemplateBase(ZSheetItem item, ZSheetView zsheet) { Item = item; ZSheet = zsheet; } #region Implementation of IBindableTemplate public void InstantiateIn(Control container) { EditorControl = CreateControl(); container.Controls.Add(EditorControl); } public virtual IOrderedDictionary ExtractValues(Control container) { OrderedDictionary od = new OrderedDictionary { { Item.caption, GetValue() } }; return od; } #endregion protected virtual object GetValue() { switch (Item.ItemType) { case ZSheetItemDataType.Date: return ((RadDatePicker) EditorControl).SelectedDate; case ZSheetItemDataType.Time: return ((RadTimePicker)EditorControl).SelectedDate; case ZSheetItemDataType.DateTime: return ((RadDateTimePicker)EditorControl).SelectedDate; default: return ((RadTextBox)EditorControl).Text; } } protected virtual WebControl CreateControl() { WebControl result = null; switch (Item.ItemType) { case ZSheetItemDataType.Date: result = new RadDatePicker(); break; case ZSheetItemDataType.Time: result = new RadTimePicker(); break; case ZSheetItemDataType.DateTime: result = new RadDateTimePicker(); break; default: result = new RadTextBox(); break; } result.ID = "ctl_" + Item.f_name; result.DataBinding += ctl_DataBinding; return result; } void ctl_DataBinding(object sender, EventArgs e) { DataRowView drv = GetDataRowView(sender as WebControl); switch (Item.ItemType) { case ZSheetItemDataType.Date: ((RadDatePicker)sender).SelectedDate = Convert.ToDateTime(drv[Item.user_name]); break; case ZSheetItemDataType.Time: ((RadTimePicker)sender).SelectedDate = Convert.ToDateTime(drv[Item.user_name]); break; case ZSheetItemDataType.DateTime: ((RadDateTimePicker)sender).SelectedDate = Convert.ToDateTime(drv[Item.user_name]); break; default: ((RadTextBox)sender).Text = drv[Item.user_name].ToString(); break; } } protected DataRowView GetDataRowView(WebControl control) { GridDataItem dataItem = control.NamingContainer as GridDataItem; if (dataItem == null) return null; return (DataRowView)dataItem.DataItem;}
Hope this would be enough :)
Thank you for the sample code. It seems fine, though. You seem to properly initialize custom template columns. Can you also show us how do you add them to the grid and how do you initialize the grid itself. Note that, as suggested in the RadGrid programmatic creation help topic, you need to initialize the entire grid in the Init phase of your page. This is also where columns should be added to the RadGrid.MasterTableView.Columns collection.
Greetings,
Veli
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

Yes, you need to create the entire RadGrid in the Init phase. Due to the way the control tracks its column state, if columns are created in the Init phase, then RadGrid itself should be created programmatically in the same place. Columns should be added to the RadGrid.MasterTableView.Columns collection before RadGrid itself is added to the Page's Control collection. Otherwise, you can get unexpected loss of columns, prevented event bubbling, loss of data or duplicated columns.
Veli
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

I did that, but problem still remains and ItemUpdated event won't ever fire. Below is my code
Grid = new RadGrid() { ID = "Grid", Height = Unit.Percentage(99.5), ShowStatusBar = true, AllowSorting = true, AllowFilteringByColumn = true, AutoGenerateColumns = false, AllowPaging = true, EnableLinqExpressions = true, PageSize = 20, CellSpacing = 0, AllowMultiRowSelection = true }; Grid.ItemUpdated += Grid_ItemUpdated; Grid.NeedDataSource += Grid_NeedDataSource; Grid.MasterTableView.DataKeyNames = new[] {"id"}; Grid.MasterTableView.Width = Unit.Percentage(100); Grid.MasterTableView.TableLayout = GridTableLayout.Fixed; Grid.MasterTableView.EnableColumnsViewState = false; Grid.MasterTableView.EditMode = GridEditMode.InPlace; Grid.ClientSettings.Resizing.AllowColumnResize = true; Grid.ClientSettings.Scrolling.AllowScroll = true; Grid.ClientSettings.Scrolling.UseStaticHeaders = true; Grid.ClientSettings.Selecting.AllowRowSelect = true; Grid.ClientSettings.ClientEvents.OnRowContextMenu = "showGridContextMenu"; Grid.ClientSettings.ClientEvents.OnRowClick = "RowClick"; Grid.ClientSettings.ClientEvents.OnRowDblClick = "RowDblClick"; Grid.ClientSettings.ClientEvents.OnGridCreated = "GridCreated"; Grid.ClientSettings.ClientEvents.OnCommand = "GridCommand"; CreateColumns();Panel1.Controls.Add(Grid);
Veli
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

Thank you.
Veli
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

You use the UpdateCommand event to extract your edited values and save them programmatically in your database:
protected
void
RadGrid1_UpdateCommand(
object
sender, GridCommandEventArgs e)
{
GridEditableItem editItem = (GridEditableItem)e.Item;
Hashtable newValues =
new
Hashtable();
editItem.ExtractValues(newValues);
//newValues contains your extracted values. use them to update your data
}
Alternatively, the ItemCommand event can be used:
protected
void
RadGrid1_ItemCommand(
object
sender, GridCommandEventArgs e)
{
if
(e.CommandName == RadGrid.UpdateCommandName)
{
GridEditableItem editItem = (GridEditableItem)e.Item;
Hashtable newValues =
new
Hashtable();
editItem.ExtractValues(newValues);
//newValues contains your extracted values. use them to update your data
}
}
Veli
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

Thank you very much.