This is a migrated thread and some comments may be shown as answers.

GridDataItem Loses Reference to Cell Bound to Column

8 Answers 141 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Tonya
Top achievements
Rank 1
Tonya asked on 21 Sep 2015, 04:05 AM

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
 Next
Next
 

Thanks, in advance, for your assistance!

Tonya :)

 

 

8 Answers, 1 is accepted

Sort by
0
Tonya
Top achievements
Rank 1
answered on 22 Sep 2015, 06:51 PM

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 = Nothing
Dim strDataElementID As String = Nothing
 
For 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
    Next
Next
 

 

 

0
Kostadin
Telerik team
answered on 23 Sep 2015, 11:08 AM
Hello Tonya,

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 If
Next


Regards,
Kostadin
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Tonya
Top achievements
Rank 1
answered on 24 Sep 2015, 01:37 AM

Thank you for this information.

I actually resolved things by moving the following statement down to the next level

If blnSet Then
     Exit For
End If

But 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.

 

 

0
Kostadin
Telerik team
answered on 28 Sep 2015, 11:04 AM
Hello Tonya,

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
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Tonya
Top achievements
Rank 1
answered on 28 Sep 2015, 08:54 PM

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 1​35, 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

0
Kostadin
Telerik team
answered on 01 Oct 2015, 01:26 PM
Hello 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
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Tonya
Top achievements
Rank 1
answered on 01 Oct 2015, 05:54 PM

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 1​00+ 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

 

0
Tonya
Top achievements
Rank 1
answered on 03 Oct 2015, 12:48 AM

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!

Tags
Grid
Asked by
Tonya
Top achievements
Rank 1
Answers by
Tonya
Top achievements
Rank 1
Kostadin
Telerik team
Share this question
or