I have a hierarchy grid with a GridClientSelectColumn in the child grid & I'm trying to select the boxes that meet user selected criteria on the page. I am able search through the children of the first parent row & select the matching record(s), but after finding the match it loses reference to the parent row & gives me an error stating it "Cannot find a cell bound to column name 'ProjectID'". When I step through the code, I see that the key value of my GridDataItem is no longer pointing to the ID of the parent (ProjectID), but to the child (DataElementID)! While stepping through the code, if I allow things to bypass the error & iterate through a few times, it will eventually return to the key value to the parent & then find the next match. ???
Can someone please explain to me why this is happening?
Here is a snippet of my code...
<telerik:RadGrid ID="RadGrid1" runat="server" ShowStatusBar="false" AutoGenerateColumns="False" PageSize="50" AllowSorting="True" AllowMultiRowSelection="true" AllowPaging="false" GridLines="none" OnDetailTableDataBind="RadGrid1_DetailTableDataBind" OnNeedDataSource="RadGrid1_NeedDataSource" Width="700px" ClientSettings-Scrolling-AllowScroll="true" OnPreRender="RadGrid1_PreRender" ClientSettings-Scrolling-UseStaticHeaders="true" OnItemDataBound="RadGrid1_ItemDataBound" > <MasterTableView DataKeyNames="ProjectID" AllowMultiColumnSorting="false" HierarchyLoadMode="ServerBind" > <DetailTables> <telerik:GridTableView DataKeyNames="DataElementID" Name="DataElementID" Width="100%"> <%-- Child --%> <HeaderStyle Font-Bold="true"/> <Columns> <telerik:GridClientSelectColumn UniqueName="deSelectColumn" HeaderStyle-Width="5%" ></telerik:GridClientSelectColumn> <telerik:GridTemplateColumn UniqueName="first" HeaderText="1st" HeaderStyle-Width="5%"> <ItemTemplate> <asp:CheckBox ID="CheckBox1" runat="server" /> </ItemTemplate> </telerik:GridTemplateColumn> <telerik:GridBoundColumn DataField="DataElementID" UniqueName="DataElementID" HeaderText="Data Element ID" DataType="System.Int16" HeaderStyle-Width="20%" Display="true" /> <telerik:GridBoundColumn DataField="ProjectAreaDescription" UniqueName="ProjectAreaDescription" HeaderText="Project Area Description" DataType="System.String" HeaderStyle-Width="40%" /> <telerik:GridBoundColumn DataField="ProjectDataType" UniqueName="ProjectDataType" HeaderText="Project Data Type" DataType="System.String" HeaderStyle-Width="30%" /> </Columns> </telerik:GridTableView> </DetailTables> <%-- Parent --%> <HeaderStyle Font-Bold="true"/> <Columns> <telerik:GridBoundColumn DataField="ProjectID" UniqueName="ProjectID" HeaderText="Project ID" DataType="System.Int16" Groupable="true" HeaderStyle-Width="20%" Display="true" /> <telerik:GridBoundColumn DataField="ProjectNumber" UniqueName="ProjectNumber" HeaderText="Project Number" SortExpression="ProjectNumber" DataType="System.String" HeaderStyle-Width="20%" /> <telerik:GridBoundColumn DataField="ContractNumber" UniqueName="ContractNumber" HeaderText="Contract Number" SortExpression="ContractNumber" DataType="System.String" HeaderStyle-Width="20%" /> <telerik:GridBoundColumn DataField="ProjectName" UniqueName="ProjectName" HeaderText="Project Name" SortExpression="ProjectNumber" DataType="System.String" HeaderStyle-Width="40%" /> </Columns> </MasterTableView> <ClientSettings> <Scrolling AllowScroll="true" UseStaticHeaders="true" /> <Resizing AllowColumnResize="false" /> <Selecting AllowRowSelect="True" UseClientSelectColumnOnly="true" /> </ClientSettings></telerik:RadGrid>
The following code is part of a button click that performs other operations & then performs the selection of the child records that meet the criteria. At the time of selecting the records, I know the value of both the ProjectID (parent) & DataElementID (child). Either way, when I perform the selection I'm running into errors. By the way, currently there are about 700 child records rolled up into about 250 parents.
For Each radRow As GridDataItem In RadGrid1.Items Dim strID As String = Nothing strID = radRow("ProjectID").Text For i = 0 To arrProjectID.Count - 1 If strID = arrProjectID(i).ToString Then radRow.Expanded = True radRow.ChildItem.NestedTableViews(0).Items(0).Selected = True Exit For End If NextNextThanks, in advance, for your assistance!
Tonya :)
8 Answers, 1 is accepted
I modified my code to better illustrate things. In doing so, I've come to realize that if I collapse all parent rows & comment out the inner code, things loop correctly. It's when I expand a parent row that things get off. After completing the loop of an expanded row, the KeyValue switches from the parent to the child record & then loops through all of the child records, before returning control to the parent. If I manually step out of the secondary loop, things works as I want. How can I stop it from passing the control from the parent grid to the child? Or how can I bypass this secondary looping?
Dim strProjectID As String = NothingDim strDataElementID As String = NothingFor Each parentRow As GridDataItem In RadGrid1.Items strProjectID = parentRow("ProjectID").Text For i = 0 To arrProjectID.Count - 1 If strProjectID = arrProjectID(i).ToString Then 'Expand the project row parentRow.Expanded = True Dim blnSet As Boolean = False For Each childRow As GridDataItem In parentRow.ChildItem.NestedTableViews(0).Items strDataElementID = childRow("DataElementID").Text For j = 0 To arrDataElementID.Count - 1 If strDataElementID = arrDataElementID(j).ToString Then 'Select the data element row childRow.Selected = True blnSet = True Exit For End If Next 'No need to keep looping if a match was found If blnSet Then Exit For End If Next Exit For End If NextNext
Note that OnItemDataBound event handler fires for all GridItems no matter which table view they belong. A simple solution is to set a Name to the MasterTableView and the DetailTable and this way to distinguish which items are currently bound. For instance check out the following code snippet.
<MasterTableView DataKeyNames="ProjectID" AllowMultiColumnSorting="false" HierarchyLoadMode="ServerBind" Name="Master" >For Each radRow As GridDataItem In RadGrid1.Items If radRow.OwnerTableView.Name = "MasterTable" Then
'your code
End IfNextRegards,
Kostadin
Telerik
Thank you for this information.
I actually resolved things by moving the following statement down to the next level
If blnSet Then Exit ForEnd IfBut to ensure it doesn't fail, I've wrapped things in the IF statement, as you advised.
Now my grid works as expected & the code loops through & selects the appropriate checkboxes. Yay!
However... sometimes when it's done it rebinds the grid & loses all of my selections. :( I tested a few of my criteria selections & found that if the criteria generate 35 child matches, it works. If it generates 134 matches, it works. But when it generates 155 or 190 matches, it fails because it will invoke RadGrid1_NeedDataSource & reset the grid.
So it seems the grid is still losing it's reference somehow.
Note that the selection is not persist during Rebind of the grid. Nevertheless you can persist them manually either on the client or on the server by using the approaches form the following help articles.
Persisting the Selected Rows Client-side
Persisting the Selected Rows Server-side
Regards,
Kostadin
Telerik
Hi Kostadin-
I will look into the persisting information you provided.
However, I'd still like to know why it works sometimes & not others. I'm not wanting to do a rebind, it does it on its own when things don't work correctly. When things work as I expect, the rebind doesn't happen.
Here is the scenario that needs to happen...
Users will select criteria elsewhere on the screen that generate Data Element IDs (the row ID at the child level). From that I am creating the list of Project IDs (the row ID at the parent level). One by one, I am expanding the parent row (if it matches one of the Project IDs in my array) & looping through its child rows to see if any match the Data Element IDs in my array & if a match is found, I'm selecting the child row.
The problem I'm having is that this works sometimes & not others. When it doesn't work, while stepping through the code I've found that it will rebind the grid - sometimes in the middle of the looping process & again at the end, other times just at the end of the process. Yet, I don't want it to rebind at all, because that clears out all of the selections. In some rudimentary testing I did, it seemed that when the number of Data Element IDs returned from my external process was less than 135, everything worked without incident.
Is there a limit to the number of loops the grid can perform in a single session? Is there a timeout limit that's being hit?
Tonya
Note that there is no limit set by the grid but if you think the session is timed out then you can increase it in your web.config file. Also you can check for any server or client exception which might occurs during the loop and rebind the grid. Additionally if you are able to replicate the issue in a small runnable sample I will examine it locally.
Regards,
Kostadin
Telerik
Kostadin-
I don't think the session is timing out. I believe it's looping through all of the records, it just loses something after looping too many times.
As I stated before, my scenario is...
[quote]Users will select criteria elsewhere on the screen that generate Data Element IDs (the row ID at the child level). From that I am creating the list of Project IDs (the row ID at the parent level). One by one, I am expanding the parent row (if it matches one of the Project IDs in my array) & looping through its child rows to see if any match the Data Element IDs in my array & if a match is found, I'm selecting the child row.[quote]
Currently there are about 270 parent records & 760 child records. This will grow!
If there are only 10 child matches to be found, I don't expand every parent & loop through every child - I only expand those parents where I know a match will be found. From what I can tell, the problem happens when I have 100+ child matches. The process of expanding the parents & looping through the children will complete, but it loses something along the way. Again, if the number of matches it needs to find is less than 35, everything works as expected. The problem is, I have no way of knowing how many matches my customers will generate when selecting their criteria, so I can't have this arbitrary limitation happen.
I've stopped using RadGrid1_NeedDataSource & now have a custom bind method, so that I may modify the data source when needed. Doing this has stopped the code from rebinding, however, now after completing the loop (with 100+ matches) the grid isn't displayed at all (the default of the page)... it's as if it loses reference to itself or as if the page itself is refreshing - but I don't see that happening.
Below are snippets from my code, in hopes that it will help you to help me. :)
Thanks!
Tonya
*****************
Grid
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server"><AjaxSettings> <telerik:AjaxSetting AjaxControlID="RadGrid1"> <UpdatedControls> <telerik:AjaxUpdatedControl ControlID="RadGrid1" LoadingPanelID="RadAjaxLoadingPanel1" /> </UpdatedControls> </telerik:AjaxSetting></AjaxSettings></telerik:RadAjaxManager><telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" /><telerik:RadGrid ID="RadGrid1" runat="server" ShowStatusBar="false" AutoGenerateColumns="False" AllowSorting="True" AllowMultiRowSelection="true" AllowPaging="false" GridLines="none" ShowFooter="true" OnDetailTableDataBind="RadGrid1_DetailTableDataBind" ClientSettings-Scrolling-AllowScroll="true" ClientSettings-Scrolling-UseStaticHeaders="true" > <MasterTableView DataKeyNames="ProjectID" AllowMultiColumnSorting="false" HierarchyLoadMode="Conditional" Name="ParentGrid" ShowFooter="true" > <DetailTables> <telerik:GridTableView DataKeyNames="DataElementID" Name="DataElementID" Width="100%" > <%-- Child --%> <HeaderStyle Font-Bold="true"/> <Columns> <telerik:GridClientSelectColumn UniqueName="deSelectColumn" HeaderStyle-Width="5%" ></telerik:GridClientSelectColumn> <telerik:GridTemplateColumn UniqueName="firstColumn" HeaderText="1st" HeaderStyle-Width="5%"> <ItemTemplate> <asp:CheckBox ID="CheckBox1" runat="server" /> </ItemTemplate> </telerik:GridTemplateColumn> <telerik:GridBoundColumn DataField="DataElementID" UniqueName="DataElementID" HeaderText="Data Element ID" DataType="System.Int16" Display="false" /> <telerik:GridBoundColumn DataField="ProjectAreaDescription" UniqueName="ProjectAreaDescription" HeaderText="Project Area Description" DataType="System.String" HeaderStyle-Width="50%" /> <telerik:GridBoundColumn DataField="ProjectDataType" UniqueName="ProjectDataType" HeaderText="Project Data Type" DataType="System.String" HeaderStyle-Width="40%" /> </Columns> </telerik:GridTableView> </DetailTables> <%-- Parent --%> <HeaderStyle Font-Bold="true"/> <Columns> <telerik:GridBoundColumn DataField="ProjectID" UniqueName="ProjectID" HeaderText="Project ID" DataType="System.Int16" Groupable="true" Display="false" /> <telerik:GridBoundColumn DataField="ProjectNumber" UniqueName="ProjectNumber" HeaderText="Project Number" DataType="System.String" HeaderStyle-Width="20%" Aggregate="Count" FooterText="Total Number of Distict Projects: " /> <telerik:GridBoundColumn DataField="ContractNumber" UniqueName="ContractNumber" HeaderText="Contract Number" DataType="System.String" HeaderStyle-Width="20%" Aggregate="Count" FooterText="Total Number of Distict Projects: " /> <telerik:GridBoundColumn DataField="ProjectName" UniqueName="ProjectName" HeaderText="Project Name" DataType="System.String" HeaderStyle-Width="60%" Aggregate="Custom" FooterText="Total Number Selected: " /> </Columns> </MasterTableView> <ClientSettings> <Scrolling AllowScroll="true" UseStaticHeaders="true" /> <Resizing AllowColumnResize="false" /> <Selecting AllowRowSelect="True" UseClientSelectColumnOnly="true" /> </ClientSettings></telerik:RadGrid>VB Code
''' <summary>''' Handle the btnFilter OnClick event''' </summary>''' <param name="sender"></param>''' <param name="e"></param>Protected Sub btnFilter_OnClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFilter.Click '*** other code *** '********** ' In the code below, the following variables are used to find matches in the Telerk grid ' * arrProjectID (parent grid) ' * arrDataElementID (child grid) ' There can be 1 to many arrDataElementID values, assocated with each arrProjectID value. ' Currently, in my database there are about 270 arrProjectID values & 760 arrDataElementID values. ' I have a few counts in the code (some for debugging purposes), even when it fails to do things properly ' the counts are correct. ' After looping through the code, intCount2 should be equal to the number of parent rows in the grid. ' The value of intTotalSelected should reflect the number of child records selected - the value of arrDataElementID. ' When arrProjectID.count = 35 & arrDataElementID.count = 35, things work. ' When arrProjectID.count = 40 & arrDataElementID.count = 134, things fail. Under this scenario, if I manually stop ' the looping after 110 matches, it works. ' So the problem is definitely tied to the number of matches it tries to find '********** Dim strProjectID As String = Nothing Dim strDataElementID As String = Nothing Dim blnSelected As Boolean = False '*** For Debugging *** Dim intCount As Integer = 0 Dim intCount2 As Integer = 0 '*** For Debugging *** intTotalSelected = 0 For Each parentRow As GridDataItem In RadGrid1.Items If parentRow.OwnerTableView.Name = "ParentGrid" Then strProjectID = parentRow("ProjectID").Text For i = 0 To arrProjectID.Count - 1 If strProjectID = arrProjectID(i).ToString Then 'Expand the project row parentRow.Expanded = True blnSelected = False For Each childRow As GridDataItem In parentRow.ChildItem.NestedTableViews(0).Items strDataElementID = childRow("DataElementID").Text For j = 0 To arrDataElementID.Count - 1 If strDataElementID = arrDataElementID(j).ToString Then 'Select the data element row childRow.Selected = True blnSelected = True 'Set the total selected count lblTotalSelected.Text = lblTotalSelected.Text + 1 intTotalSelected = intTotalSelected + 1 'No need to keep looping if a match was found Exit For End If Next Next '*** For Debugging *** intCount = intCount + 1 'The number of parent rows that were expanded (arrProjectID.count) '*** For Debugging *** 'No need to keep looping if a match was found If blnSelected Then Exit For End If End If Next '*** For Debugging *** intCount2 = intCount2 + 1 'The number of parent rows in the table '*** For Debugging *** End If Next '*** other code *** End Sub''' <summary>''' Builds the Telerik Grid control''' </summary>''' <param name="arrSource"></param>Private Sub BuildGrid(Optional ByVal arrSource As ArrayList = Nothing) Dim intTotalItems As Integer = 0 If Not arrSource Is Nothing Then If Not arrSource.Count = 0 Then Dim myCollection As EMSProjects Dim myDataSource As New EMSProjects Dim _projectsMgr As ProjectManager = Nothing _projectsMgr = New ProjectManager(MyBase.CurrentUser) myCollection = _projectsMgr.GetAllProjects() If arrSource.Item(0).ToString <> "ALL" Then For Each item In myCollection.Items For i = 0 To arrSource.Count - 1 If item.ProjectID = arrSource(i) Then If Not myDataSource.Items.Contains(item) Then myDataSource.Items.Add(item) End If Exit For End If Next Next Else myDataSource = myCollection End If If Not myDataSource Is Nothing Then RadGrid1.DataSource = myDataSource.Items lblTotalItems.Text = myDataSource.Count intTotalItems = myDataSource.Count Else RadGrid1.DataSource = "" lblTotalItems.Text = 0 intTotalItems = 0 End If End If End If RadGrid1.Rebind()End Sub ''' <summary> ''' Handles the RadGrid1.DetailTableDataBind event ''' </summary> ''' <param name="source"></param> ''' <param name="e"></param> Protected Sub RadGrid1_DetailTableDataBind(ByVal source As Object, ByVal e As GridDetailTableDataBindEventArgs) Handles RadGrid1.DetailTableDataBind Dim myCollection As EMSDataElements Dim _dataElementsMgr As DataElementManager = Nothing _dataElementsMgr = New DataElementManager(MyBase.CurrentUser) Dim dataItem As GridDataItem = DirectCast(e.DetailTableView.ParentItem, GridDataItem) Dim strProjectID As String = dataItem.GetDataKeyValue("ProjectID").ToString() myCollection = _dataElementsMgr.GetDataElementsList(0, 0, 0, CInt(strProjectID)) e.DetailTableView.DataSource = myCollection.Items End Sub
This has been resolved! I'm not sure which item fixed things, but I added the following & now things work when there are 150+ items to be checked.
Added RadAjaxLoadingPanel & RadAjaxPanel to my ASPX file
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server"> <AjaxSettings> <telerik:AjaxSetting AjaxControlID="RadGrid1"> <UpdatedControls> <%--<telerik:AjaxUpdatedControl ControlID="RadGrid1" /> --%> <telerik:AjaxUpdatedControl ControlID="RadGrid1" LoadingPanelID="RadAjaxLoadingPanel1" /> </UpdatedControls> </telerik:AjaxSetting> </AjaxSettings></telerik:RadAjaxManager><telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" /><telerik:RadAjaxPanel runat="server" ID="RadAjaxPanel" LoadingPanelID="RadAjaxLoadingPanel1" >Added a reference to System.Windows.Forms, Version=4.0.0.0 - previously it was referencing 3.5 & on my last build I received a warning that Telerik version 2015.2.826 may have compatibility issues with it. It's interesting that I hadn't gotten this warning before.
<add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>In any case, things are working now.
Tonya!