Hi,
I am creating a grid at runtime with viewstate enabled. I have a few columns that I am adding to this grid, again, at runtime. The item template and edit item template both have custom templates (that implement ITemplate and IBindableTemplate). And I have textboxes in these columns.
After I present the entire grid in edit mode, upon save, the textbox controls within these columns are "lost" upon postback. I am not able to retrieve them using findcontrol. The custom column definitions are there (but not the textboxes) and also available are the edit item count (basically the number of rows that the grid has in edit). Once I get past this challenge, my hope is to use the built-in functionality to extract the values that changed while editing (exported in HashTable format).
So my question is how can I get the controls from the item collection upon postback (without getting it lost)?
Thanks in advance for any help you can provide.
Let me know if you need to see any other code samples.
Thanks,
RN
I am creating a grid at runtime with viewstate enabled. I have a few columns that I am adding to this grid, again, at runtime. The item template and edit item template both have custom templates (that implement ITemplate and IBindableTemplate). And I have textboxes in these columns.
After I present the entire grid in edit mode, upon save, the textbox controls within these columns are "lost" upon postback. I am not able to retrieve them using findcontrol. The custom column definitions are there (but not the textboxes) and also available are the edit item count (basically the number of rows that the grid has in edit). Once I get past this challenge, my hope is to use the built-in functionality to extract the values that changed while editing (exported in HashTable format).
So my question is how can I get the controls from the item collection upon postback (without getting it lost)?
Thanks in advance for any help you can provide.
Let me know if you need to see any other code samples.
Thanks,
RN
| Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender |
| 'grid to display the header |
| CreateHeaderGridStructure() |
| 'grid to display the details (w/o header) |
| CreateDetailGridStructure() |
| grdDetail.Rebind() |
| End Sub |
| Private Function CreateDetailGridStructure() As Boolean |
| 'get the column metadata to create the column input boxes. |
| Dim drTemplateDetails As IDataReader |
| Dim templateColumn As GridTemplateColumn |
| grdDetail.MasterTableView.Columns.Clear() |
| grdDetail.MasterTableView.DetailTables.Item(0).AutoGenerateColumns = False |
| grdDetail.MasterTableView.ExpandCollapseColumn.ItemStyle.Width = Unit.Percentage(4) |
| columnDefinitions = New System.Collections.Generic.List(Of GridColumnDefinition) |
| drTemplateDetails = 'Get the data here |
| While drTemplateDetails.Read() |
| templateColumn = New GridTemplateColumn() |
| templateColumn.DataField = <the column name> |
| templateColumn.UniqueName = <the column name> templateColumn.ItemTemplate = New GridDetailTemplate(<the column name>, Me.ClientID, ControlType.Label) |
| If <if only viewable column with no edit> Then |
| templateColumn.EditItemTemplate = New GridDetailTemplate(columnDefinition.Name, Me.ClientID, ControlType.Label) |
| If columnDefinition.Type = GridColumnType.Hidden Then |
| templateColumn.Display = False |
| End If |
| Else |
| 'if the grid is in edit mode, then inEditMode = True |
| If inEditMode Then |
| templateColumn.EditItemTemplate = New GridDetailTemplate(columnDefinition.Name, Me.ClientID, ControlType.PremiumTextBox) |
| Else |
| templateColumn.EditItemTemplate = New GridDetailTemplate(columnDefinition.Name, Me.ClientID, ControlType.Label) |
| End If |
| End If |
| grdDetail.MasterTableView.Columns.Add(templateColumn) |
| End While |
| End Function |
| Private Sub grdDetail_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles grdDetail.PreRender |
| 'If using itemtemplate/edititemtemplate, then use the following to set the grid in edit mode. |
| 'todo: look to combine these following if logics into one |
| If inEditMode Then |
| If IsPostBack Then |
| For Each item As GridItem In grdDetail.MasterTableView.Items |
| If TypeOf item Is GridEditableItem Then |
| Dim editableItem As GridEditableItem = CType(item, GridDataItem) |
| editableItem.Edit = True |
| End If |
| Next |
| grdDetail.Rebind() |
| End If |
| End If |
| End Function |
| Public Class GridDetailTemplate |
| Implements ITemplate, System.Web.UI.IBindableTemplate |
| Private controlID As String |
| Private clientID As String |
| Private type As ControlType |
| 'This is the only public constructor. Should also accept the kind of control that needs to be created |
| Public Sub New(ByVal controlID As String, ByVal clientID As String, ByVal type As ControlType) |
| MyBase.New() |
| Me.controlID = controlID |
| Me.clientID = clientID |
| Me.type = type |
| End Sub |
| Public Function ExtractValues(ByVal container As Control) As Collections.Specialized.IOrderedDictionary Implements IBindableTemplate.ExtractValues |
| Dim returnDictionary As Collections.Specialized.OrderedDictionary = New Collections.Specialized.OrderedDictionary() |
| Select Case type |
| Case ControlType.Label |
| returnDictionary.Add(controlID, (DirectCast(((DirectCast(container, Telerik.Web.UI.GridDataItem)).FindControl(controlID)), Label)).Text) |
| Case ControlType.PremiumTextBox |
| returnDictionary.Add(controlID, (DirectCast(((DirectCast(container, Telerik.Web.UI.GridDataItem)).FindControl(controlID)), TextBox)).Text) |
| End Select |
| Return returnDictionary |
| End Function |
| Public Sub InstantiateIn(ByVal container As Control) Implements ITemplate.InstantiateIn |
| 'create the control that we want |
| Dim control As New Control |
| Select Case type |
| Case ControlType.PremiumTextBox |
| Dim txtBox As TextBox |
| txtBox = New TextBox |
| 'attributes should be added in the item databound event to be consistent |
| txtBox.Attributes.Add("onblur", "return validateInput(this);") |
| 'txtBox.Attributes.Add("onchange", "return testInput(this);") |
| 'txtBox.Attributes.Add("onchange", "return addNumbers('" + txtBox.ClientID + "')") |
| 'should be in the textbox control |
| txtBox.MaxLength = 14 |
| txtBox.Width = Unit.Pixel(100) |
| txtBox.Style.Add("text-align", "right") |
| 'txtBox.ClientEvents.OnValueChanged = "calculateTtl" |
| 'event handler to handle the databind event |
| control = txtBox |
| AddHandler control.DataBinding, AddressOf Me.TextBox1_DataBinding |
| End Select |
| 'set the id to be an unique identifier for that row |
| control.ID = controlID |
| 'add the control to the control collection |
| container.Controls.Add(control) |
| End Function |
| Public Sub TextBox1_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs) |
| Dim textbox As TextBox = CType(sender, TextBox) |
| Dim grid As GridDataItem = CType(textbox.NamingContainer, GridDataItem) |
| Dim item1Value As String = DataBinder.Eval(grid.DataItem, controlID).ToString |
| CType(grid.FindControl(controlID), TextBox).Text = item1Value |
| End Sub |
| End Class |