Hi,
I'm using RadControls for ASP.NET AJAX Q1 2009
I have a radgrid using NeedDataSource to bind to a dynamicallyt created datasource, depending on columns the user has selected. The grid is created in page_init as recommended to me.
I dynamically create the grid columns myself. One fo these columns is a template column containing a radeditor. I was advised to create columns, especially templated columns, in page_init. When I do this though, I get
I'm using RadControls for ASP.NET AJAX Q1 2009
I have a radgrid using NeedDataSource to bind to a dynamicallyt created datasource, depending on columns the user has selected. The grid is created in page_init as recommended to me.
I dynamically create the grid columns myself. One fo these columns is a template column containing a radeditor. I was advised to create columns, especially templated columns, in page_init. When I do this though, I get
Multiple controls with the same ID 'FilterTextBox_tblT1Devices.Name' were found. FindControl requires that controls have unique IDs.
If I create the columns in page load I don't get this message but my template column will disappear after postback as expected, because it's viewstate is not saved.
Another issue is my dynamically created dropdown columns are completely blank no matter what way I configure them. I have had problems with them for days. I'm hoping their problem might be related.
Please advise.
Relevant code :
| Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init |
| ' If loading for the first time... |
| 'Create the Grid |
| Dim grid As New RadGrid() |
| grid.ID = "gridServers" |
| grid.Skin = "Default" |
| grid.PageSize = 100 |
| grid.AllowPaging = True |
| grid.AllowFilteringByColumn = True |
| grid.AllowSorting = True |
| grid.ShowGroupPanel = True |
| grid.PagerStyle.Mode = GridPagerMode.NextPrevAndNumeric |
| grid.AutoGenerateColumns = False |
| grid.CssClass = "gridServers" |
| AddHandler grid.ColumnCreated, AddressOf gridServers_ColumnCreated |
| AddHandler grid.NeedDataSource, AddressOf gridServers_NeedDataSource |
| gridServersHere.Controls.Add(grid) |
| ' Initialize the page |
| Initialize() |
| rptColumnSelector.DataSource = Session("showColumns") |
| rptColumnSelector.DataBind() |
| PrepareGridColumns() |
| End Sub |
| Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load |
| ' If loading for the first time... |
| If Not Page.IsPostBack Then |
| ' Initialize the page |
| 'Initialize() |
| 'PrepareGridColumns() |
| rptColumnSelector.DataSource = Session("showColumns") |
| rptColumnSelector.DataBind() |
| 'gridServers.DataBind() |
| End If |
| End Sub |
| Protected Function getDataString() As String |
| Dim columnList As Data.DataTable = Session("showColumns") |
| Dim selectStr As String = "" |
| Dim joinstr As String = "" |
| Dim column As Data.DataRow |
| Dim i = 0 |
| selectStr = "select tblT1Devices.DeviceID as [Device ID], tblT2Configuration.EnvironmentID as [ThisID] " |
| 'build a comma-delimited list of columns that will make up the SQL Query. |
| 'Dont put a comma after the last one. |
| If columnList Is Nothing Then |
| Initialize() |
| columnList = Session("showColumns") |
| End If |
| For Each column In columnList.Rows |
| ' Process only the checked columns. |
| If column("Checked") = True Then |
| selectStr = selectStr + ", " + column("FullName") + " as [" + column("FullName") + "]" |
| ' Commented out at the moment. We are doing the simple version above. |
| ' Select Case column("LookupTable") |
| ' If this is a straight forward field : |
| ' Case "" |
| ' selectStr = selectStr + ", " + column("FullName") + " as [" + column("FullName") + "]" |
| 'Otherwise is must be a lookup ID : |
| ' Case Else |
| ' selectStr = selectStr + ", " |
| ' selectStr = selectStr + column("TABLE_NAME") + column("COLUMN_NAME") + "." + column("LookupValue") + " as [" + column("FullName") + "]" |
| 'Join Str is a string we're contructing of SQL Joins, while we'rein the same loop. This will be tagged on the end of |
| 'selectstr after this loop. |
| ' joinstr = joinstr + " left join " + column("LookupTable") + " as " + column("TABLE_NAME") + column("COLUMN_NAME") |
| ' joinstr = joinstr + " on " + column("TABLE_NAME") + column("COLUMN_NAME") + "." + column("LookupID") + " = " + column("FullName") |
| ' End Select |
| End If |
| 'If i < columnCount Then selectStr = selectStr + "," |
| 'i += 1 |
| Next |
| selectStr = selectStr + " from tblT1Devices left join tblt2configuration on tblT2configuration.deviceID = tblT1Devices.deviceid" |
| selectStr = selectStr + " left join tblt3_MV_Configuration on tblT3_MV_Configuration.deviceID = tblT1Devices.deviceid" |
| 'selectStr = selectStr + joinstr |
| Return selectStr |
| End Function |
| Protected Sub Initialize() |
| Dim column As DataRow |
| Dim ColumnList As Data.DataTable = CreateColumnListDataTable() |
| 'A list of Column Names we want to show by default on the Grid: |
| Dim SelectedColumns As String() = {"tblT1Devices.Name", "tblT1Devices.Domain"} |
| Dim selectColumn As String |
| 'Get all available columns from the SP |
| Dim ConnString As String = ConfigurationManager.ConnectionStrings("WPG_ADBConnectionString").ConnectionString |
| Dim conn As SqlConnection = New SqlConnection(ConnString) |
| Dim adapter As SqlDataAdapter = New SqlDataAdapter |
| adapter.SelectCommand = New SqlCommand("exec sp_web_Search_GetAvailableColumns", conn) |
| Dim table1 As New DataTable |
| conn.Open() |
| Try |
| adapter.Fill(table1) |
| Finally |
| conn.Close() |
| End Try |
| 'We add a column here that will hold whether the column is checked on the GUI |
| 'Then Cycle through all the checkboxes and check those that match the default list above |
| Dim myDataColumn As DataColumn |
| myDataColumn = New DataColumn() |
| myDataColumn.DataType = Type.GetType("System.Boolean") |
| myDataColumn.ColumnName = "Checked" |
| table1.Columns.Add(myDataColumn) |
| For Each column In table1.Rows |
| column("Checked") = False ' Check them all to false by default. |
| For Each selectColumn In SelectedColumns |
| If selectColumn = column("FullName") Then |
| column("Checked") = True 'check them to true if in the list above. |
| End If |
| Next |
| Next |
| 'Set the FullName Column as the PrimaryKey |
| 'Dim Key() As DataColumn |
| 'Key(0) = table1.Columns("FullName") |
| 'Key(0) = table1.Columns.Item("FullName") |
| 'table1.PrimaryKey = Key |
| 'For Each item In rpt.Items |
| ' chk = item.FindControl("chkColumn") |
| 'chkColumn = chk.ToolTip.Split("-") |
| 'For Each selectColumn In SelectedColumns |
| ' If selectColumn = chkColumn(0) Then |
| ' chk.Checked = "true" |
| 'End If |
| 'Next |
| 'Next |
| 'update the session variable of checked columns |
| Session("showColumns") = table1 |
| End Sub |
| Protected Sub gridServers_ColumnCreated(ByVal sender As Object, ByVal e As Telerik.Web.UI.GridColumnCreatedEventArgs) |
| Dim ColumnList As DataTable = Session("showColumns") |
| Dim myColumn As DataRow |
| 'Go through all columns and perform specific tasks depending on row types. |
| For Each myColumn In ColumnList.Rows |
| 'For any columns in the grid that match our datatable of extra column data ... : |
| 'If e.Column.UniqueName = myColumn("FullName") Then |
| ' e.Column.HeaderText = myColumn("FriendlyColumnName") |
| 'e.Column.HeaderTooltip = e.Column.HeaderTooltip + " - " + myColumn("FullName") & " - " & myColumn("Description") |
| 'Detect column types and set to readonly if the column is readonly. |
| 'Select Case e.Column.ColumnType |
| ' Case "GridBoundColumn" |
| 'Dim boundColumn As GridBoundColumn = CType(e.Column, GridColumn) |
| 'boundColumn.ReadOnly = Boolean.Parse(myColumn("Readonly")) |
| 'If Not boundColumn.ReadOnly Then e.Column.HeaderStyle.ForeColor = System.Drawing.ColorTranslator.FromHtml("#0269ff") |
| 'Case "GridCheckBoxColumn" |
| 'Dim boundColumn As GridCheckBoxColumn = CType(e.Column, GridColumn) |
| 'boundColumn.ReadOnly = Boolean.Parse(myColumn("Readonly")) |
| 'If Not boundColumn.ReadOnly Then e.Column.HeaderStyle.ForeColor = System.Drawing.ColorTranslator.FromHtml("#0269ff") |
| 'End Select |
| 'Check for Lookup tables and change the column type to dropdowns for editing purposes |
| ' Note that the grid doesnt autodetect this osrt of thing (like checkboxes) so we have to tell it to. |
| ' Otherwise it will just use GridBoundColumn |
| 'If a lookup table is specified |
| 'If myColumn("Lookuptable") <> "" Then |
| ' e.Column.co() |
| 'End If |
| 'End If |
| 'If the column is the DeviceID, make sure this is readonly as it is the primary key. |
| If e.Column.UniqueName = "Device ID" Then |
| Dim boundColumn As GridBoundColumn = CType(e.Column, GridBoundColumn) |
| boundColumn.ReadOnly = True |
| End If |
| Next |
| ' For edit column |
| If e.Column.ColumnType = "Telerik.Web.UI.GridEditCommandColumn" Then |
| End If |
| End Sub |
| Protected Sub gridServers_UpdateCommand(ByVal source As Object, ByVal e As Telerik.Web.UI.GridCommandEventArgs) |
| Dim ColumnList As Data.DataTable = Session("showColumns") |
| Dim columnName As Data.DataRow |
| Dim sqlstring = "" |
| Dim w = "Telerik.Web.UI.GridEditFormItem" |
| 'Get the GridEditableItem of the RadGrid |
| Dim editedItem As GridEditableItem = TryCast(e.Item, GridEditableItem) |
| 'Get the primary key value using the DataKeyValue. |
| Dim DeviceID As String = editedItem.OwnerTableView.DataKeyValues(editedItem.ItemIndex)("Device ID").ToString() |
| Dim sql As SqlDataSource = New SqlDataSource |
| sql.ConnectionString = ConfigurationManager.ConnectionStrings("WPG_ADBConnectionString").ConnectionString |
| 'have to put at least one update statement (deviceid = deviceid) so anything added after has a comma before it |
| sqlstring = "Update tblT3_MV_Configuration set DeviceID = " & DeviceID & " " |
| For Each columnName In ColumnList.Rows |
| 'only if column is readonly and checked..... |
| If columnName("ReadOnly") <> "true" And columnName("Checked") Then |
| Dim name As String = editedItem(columnName(5)).controls(0).GetType().ToString() |
| Select Case editedItem(columnName("Fullname")).controls(0).GetType().ToString() |
| Case "System.Web.UI.WebControls.TextBox" |
| sqlstring = sqlstring & ", " & columnName(0) & " = '" & (TryCast(editedItem(columnName("Fullname")).Controls(0), TextBox)).Text & "', " |
| Case "System.Web.UI.WebControls.CheckBox" |
| sqlstring = sqlstring & ", " & columnName("FullName") & " = '" & (TryCast(editedItem(columnName("Fullname")).Controls(0), CheckBox)).Checked.ToString & "', " |
| Case "System.Web.UI.WebControls.dropdownlist" |
| sqlstring = sqlstring & ", " & columnName("FullName") & " = '" & (TryCast(editedItem(columnName("Fullname")).Controls(0), DropDownList)).SelectedItem.Value & "', " |
| 'might use this later : |
| 'telerik.Web.UI.RadDateInput |
| End Select |
| End If |
| Next |
| sqlstring = sqlstring & " where DeviceID = " & DeviceID |
| 'Will do update here...... |
| End Sub |
| Protected Sub gridServers_NeedDataSource(ByVal source As Object, ByVal e As Telerik.Web.UI.GridNeedDataSourceEventArgs) |
| 'Set up grid columns acording to our selected column list |
| 'Not any more, do this in Page_init |
| 'PrepareGridColumns() |
| Dim gridServers As RadGrid = source |
| Dim value() As String = {"Device ID"} |
| gridServers.DataSource = GetDataTable() |
| gridServers.MasterTableView.DataKeyNames = value |
| End Sub |
| Public Function GetDataTable() As DataTable |
| Dim ConnString As String = ConfigurationManager.ConnectionStrings("WPG_ADBConnectionString").ConnectionString |
| Dim conn As SqlConnection = New SqlConnection(ConnString) |
| Dim adapter As SqlDataAdapter = New SqlDataAdapter |
| adapter.SelectCommand = New SqlCommand(getDataString(), conn) |
| Dim table1 As New DataTable |
| conn.Open() |
| Try |
| adapter.Fill(table1) |
| Finally |
| conn.Close() |
| End Try |
| Return table1 |
| End Function |
| Public Sub PrepareGridColumns() |
| 'This function will generate the columns for the Grid by looping through the checkbox datatable |
| ' Instead of autogenerating, this way I can handpick and identify the dropdown\lookup columns |
| Dim gridServers As RadGrid = gridServersHere.FindControl("gridServers") |
| Dim column As DataRow |
| Dim columnList As DataTable = Session("showColumns") |
| Dim AnyColumnsAreEditable As Boolean = False |
| 'Clear Columns |
| gridServers.Columns.Clear() |
| Dim editcol As New GridEditCommandColumn() |
| gridServers.MasterTableView.Columns.Add(editcol) |
| Dim sql1 As New SqlDataSource |
| sql1.ID = "sqlEnv" |
| sql1.ConnectionString = ConfigurationManager.ConnectionStrings("WPG_ADBConnectionString").ConnectionString |
| sql1.SelectCommand = "select * from tblT3Environments" |
| Dim dd As New GridDropDownColumn |
| gridServers.MasterTableView.Columns.Add(dd) |
| dd.ListValueField = "EnvironmentID" |
| dd.ListTextField = "Environment" |
| dd.DataSourceID = sql1.ID |
| dd.HeaderText = "Scooby" |
| dd.DataField = "ThisID" |
| For Each column In columnList.Rows |
| If column("Checked") Then |
| If column("LookupTable") <> "" Then |
| Dim sql As New SqlDataSource |
| sql.ID = "sql" & column("Table_Name") & column("column_Name") |
| sql.ConnectionString = ConfigurationManager.ConnectionStrings("WPG_ADBConnectionString").ConnectionString |
| sql.SelectCommand = "select " & column("LookupID") & ", " & column("LookupValue") & " from " & column("LookupTable") |
| Dim dropdowncol As New GridDropDownColumn |
| gridServers.MasterTableView.Columns.Add(dropdowncol) |
| dropdowncol.ListValueField = column("LookupID") |
| dropdowncol.ListTextField = column("LookupValue") |
| dropdowncol.DataSourceID = sql.ID |
| dropdowncol.HeaderText = column("FriendlyColumnName") |
| dropdowncol.DataField = column("FullName") |
| dropdowncol.UniqueName = column("FullName") |
| dropdowncol.ReadOnly = Boolean.Parse(column("Readonly")) |
| dropdowncol.SortExpression = column("FullName") |
| dropdowncol.Groupable = True |
| dropdowncol.GroupByExpression = column("FullName") + " Group By " + column("FullName") |
| Else |
| If column("DATA_TYPE") = "varchar" Or column("DATA_TYPE") = "nvarchar" Then |
| Dim boundcol As New GridBoundColumn() |
| gridServers.MasterTableView.Columns.Add(boundcol) |
| boundcol.UniqueName = column("FullName") |
| boundcol.HeaderText = column("FriendlyColumnName") |
| boundcol.DataField = column("FullName") |
| boundcol.HeaderTooltip = boundcol.HeaderTooltip.ToString() + " - " + column("FullName") & " - " & column("Description") |
| boundcol.ReadOnly = Boolean.Parse(column("Readonly")) |
| boundcol.SortExpression = column("FullName") |
| boundcol.Groupable = True |
| boundcol.GroupByExpression = column("FullName") + " Group By " + column("FullName") |
| ElseIf column("DATA_TYPE") = "datetime" Then |
| Dim datecol As New GridDateTimeColumn() |
| gridServers.MasterTableView.Columns.Add(datecol) |
| datecol.UniqueName = column("FullName") |
| datecol.HeaderText = column("FriendlyColumnName") |
| datecol.DataField = column("FullName") |
| datecol.HeaderTooltip = datecol.HeaderTooltip.ToString() + " - " + column("FullName") & " - " & column("Description") |
| datecol.ReadOnly = Boolean.Parse(column("Readonly")) |
| datecol.PickerType = GridDateTimeColumnPickerType.DateTimePicker |
| ElseIf column("DATA_TYPE") = "int" Or column("DATA_TYPE") = "bigint" Then |
| Dim intcol As New GridNumericColumn() |
| gridServers.MasterTableView.Columns.Add(intcol) |
| intcol.UniqueName = column("FullName") |
| intcol.HeaderText = column("FriendlyColumnName") |
| intcol.DataField = column("FullName") |
| intcol.HeaderTooltip = intcol.HeaderTooltip.ToString() + " - " + column("FullName") & " - " & column("Description") |
| intcol.ReadOnly = Boolean.Parse(column("Readonly")) |
| ElseIf column("DATA_TYPE") = "text" Then |
| Dim tempcol As New GridTemplateColumn() |
| 'The class for this template can be found at the bottom of this code-behind |
| tempcol.EditItemTemplate = New MyEditBoxTemplate(column("FullName")) |
| tempcol.UniqueName = column("FullName") |
| tempcol.HeaderText = column("FriendlyColumnName") |
| tempcol.DataField = column("FullName") |
| tempcol.HeaderTooltip = tempcol.HeaderTooltip.ToString() + " - " + column("FullName") & " - " & column("Description") |
| tempcol.ReadOnly = Boolean.Parse(column("Readonly")) |
| gridServers.MasterTableView.Columns.Add(tempcol) |
| ElseIf column("DATA_TYPE") = "bit" Then |
| Dim Checkcol As New GridCheckBoxColumn() |
| gridServers.MasterTableView.Columns.Add(Checkcol) |
| Checkcol.UniqueName = column("FullName") |
| Checkcol.HeaderText = column("FriendlyColumnName") |
| Checkcol.DataField = column("FullName") |
| Checkcol.HeaderTooltip = Checkcol.HeaderTooltip.ToString() + " - " + column("FullName") & " - " & column("Description") |
| Checkcol.ReadOnly = Boolean.Parse(column("Readonly")) |
| Else |
| Dim boundcol As New GridBoundColumn() |
| gridServers.MasterTableView.Columns.Add(boundcol) |
| boundcol.UniqueName = column("FullName") |
| boundcol.HeaderText = column("FriendlyColumnName") |
| boundcol.DataField = column("FullName") |
| boundcol.HeaderStyle.ForeColor = Drawing.Color.Red |
| boundcol.HeaderTooltip = boundcol.HeaderTooltip.ToString() + " - " + column("FullName") & " - " & column("Description") |
| boundcol.ReadOnly = Boolean.Parse(column("Readonly")) |
| End If |
| End If |
| End If |
| Next |
| End Sub |
| Private Class MyEditBoxTemplate |
| Implements ITemplate |
| Protected EditBox As RadEditor |
| Private colname As String |
| Public Sub New(ByVal cName As String) |
| MyBase.New() |
| colname = cName |
| End Sub |
| Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements ITemplate.InstantiateIn |
| EditBox = New RadEditor |
| EditBox.ID = "editBox" |
| 'Format edit Box |
| EditBox.Width = "500" |
| EditBox.Width = "300" |
| Dim myTools() As String = {"ToggleScreenMode", "Bold", "Italic", "Underline", "Fontsize", "Fontname", "Cut", "Copy", "Paste", _ |
| "Undo", "Redo", "Indent", "Outdent"} |
| Dim toolname As String |
| Dim Main As New EditorToolGroup() |
| For Each toolname In myTools |
| Dim tool As New EditorTool(toolname) |
| tool.Type = EditorToolType.Button |
| Main.Tools.Add(tool) |
| Next |
| EditBox.Tools.Add(Main) |
| AddHandler EditBox.DataBinding, AddressOf Me.EditBox_DataBinding |
| container.Controls.Add(EditBox) |
| End Sub |
| Private Sub EditBox_DataBinding(ByVal sender As Object, ByVal e As EventArgs) |
| Dim eBox As RadEditor = CType(sender, RadEditor) |
| Dim container As GridEditFormItem = CType(eBox.NamingContainer, GridEditFormItem) |
| 'eBox.Content = CType(container.DataItem, DataRowView)(colname).ToString() |
| eBox.Content = "<b>Server Notes</b><br/><br/>Previous server notage may not be modified. Any notes written and saved here will be appended." |
| End Sub |
| End Class |
| End Class |