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

HierarchyLoadMode "ServerOnDemand" not working with NestedViewTemplate

2 Answers 144 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Massimiliano
Top achievements
Rank 1
Massimiliano asked on 22 Sep 2013, 06:12 PM
I'm trying to exploit the Telerik example here:
http://demos.telerik.com/aspnet-ajax/grid/examples/hierarchy/nestedviewtemplate/defaultcs.aspx
The goal is to add editing capabilities to this demo, so in the NestedViewTemplate inside the page views of RadMultiPage I have FormView to present the data.
I'm facing several little problems even if overall it seems to work well.... I will try to ask help for one issue at a time.
The first issue I'm facing is that all the details inside the NestedViewTemplate are loaded on page load even if HierarchyLoadMode is set to "Conditional" or "ServerOnDemand".
I would like, for obvious reasons, to fire the FormView bindings inside the NestedViewTemplate only when the parent row is expanded.

Any hint? (structure follows)

           <NestedViewTemplate>
<asp:Panel runat="server" ID="RadGrid1DetailContainer" CssClass="RadGridDetailContainer" Visible="false">
<telerik:RadTabStrip runat="server" ID="RadGrid1DetailTabStrip" MultiPageID="RadGrid1DetailMultipage1" SelectedIndex="0" CssClass="RadGridTabStrip">
<Tabs>
<telerik:RadTab runat="server" Text="Dati utente" PageViewID="RadGrid1DetailRadPageView1">
</telerik:RadTab>
<telerik:RadTab runat="server" Text="Anagrafica" PageViewID="RadGrid1DetailRadPageView2">
</telerik:RadTab>
  <telerik:RadTab runat="server" Text="Altri dati" PageViewID="RadGrid1DetailRadPageView3">
</telerik:RadTab>
</Tabs>
</telerik:RadTabStrip>
<telerik:RadMultiPage runat="server" ID="RadGrid1DetailMultipage1" SelectedIndex="0" RenderSelectedPageOnly="false">
<telerik:RadPageView runat="server" ID="RadGrid1DetailRadPageView1" CssClass="RadGridPageView">
<asp:Label ID="Label1" Font-Bold="true" Font-Italic="true" Text='<%#: Item.UserId%>' runat="server" Visible="false"></asp:Label>
 
<asp:FormView id="RadGrid1DetailForm1" CssClass="RadGridDetailForm" DataSourceID="UserDetailsObjectDataSource" runat="server" ItemType="Eva.Entities.EvaUser">
<ItemTemplate>
<div class="form-horizontal form-stripe" style="padding: 12px;">
<eva:FormUserDetail ID="FormUserDetail1" Item="<%# Item %>" View="Detail2" runat="server" />
 
<div class="form-actions">
<button class="btn btn-primary">
<i class="icon icon-pencil"></i> Modifica
</button>
 
</div>
 
</div>
 
</ItemTemplate>
  
</asp:FormView>
 
<asp:ObjectDataSource ID="UserDetailsObjectDataSource" runat="server" TypeName="Eva.Bll.Core.EvaUsersManager" DataObjectTypeName="Eva.Entities.EvaUser" SelectMethod="GetById">
<SelectParameters>
<asp:ControlParameter ControlID="Label1" PropertyName="Text" Type="Int32" Name="UserId"></asp:ControlParameter>
</SelectParameters>
</asp:ObjectDataSource>
</telerik:RadPageView>
 
<telerik:RadPageView runat="server" ID="RadGrid1DetailRadPageView2">
 
</telerik:RadPageView>
<telerik:RadPageView runat="server" ID="RadGrid1DetailRadPageView3">
 
</telerik:RadPageView>
</telerik:RadMultiPage>
</asp:Panel>
           </NestedViewTemplate>

Inside RadGrid ItemCommand event I check the ExpandCollapse command to set the panel visibility accordingly

' Loads inner forms details when row is expanded
If e.CommandName = RadGrid.ExpandCollapseCommandName AndAlso TypeOf e.Item Is GridDataItem Then
    DirectCast(e.Item, GridDataItem).ChildItem.FindControl("RadGrid1DetailContainer").Visible = Not e.Item.Expanded
End If

To trigger editing (expand the row and set the FormView in edit mode, always inside RadGrid ItemCommand, I linked a button to this and it works as expected

e.Item.Expanded = True
DirectCast(e.Item, GridDataItem).ChildItem.FindControl("RadGrid1DetailContainer").Visible = True
Dim gridFormView As FormView = DirectCast(e.Item, GridDataItem).ChildItem.FindControl("RadGrid1DetailContainer").FindControl("RadGrid1DetailMultipage1").FindControl("RadGrid1DetailRadPageView1").FindControl("RadGrid1DetailForm1")
gridFormView.ChangeMode(FormViewMode.Edit)

It seems that setting the panel RadGrid1DetailContainer to Visible="false" didn't help to delay the binding

2 Answers, 1 is accepted

Sort by
0
Massimiliano
Top achievements
Rank 1
answered on 23 Sep 2013, 01:53 PM
I'm testing alternative solutions. 
Since I also need a bit more flexiblity in managing FormView data sources, I'm trying to move this in code behind.
What I did so far is to remove the DataSourceID from FormView inside NestedViewTemplate and add this code to the Item_Command event of the main RadGrid, so that when a row is expanded the FormView is binded to data.

' Loads inner forms details when row is expanded
If e.CommandName = RadGrid.ExpandCollapseCommandName AndAlso TypeOf e.Item Is GridDataItem Then
    DirectCast(e.Item, GridDataItem).ChildItem.FindControl("RadGrid1DetailContainer").Visible = Not e.Item.Expanded
    If Not e.Item.Expanded Then
        Dim gridFormView As FormView = DirectCast(e.Item, GridDataItem).ChildItem.FindControl("RadGrid1DetailContainer").FindControl("RadGrid1DetailMultipage1").FindControl("RadGrid1DetailRadPageView1").FindControl("RadGrid1DetailForm1")
 
        Dim userDetailManager As New EvaVwUserDetailBaseManager
        Dim queryData As New PagedQuery
        queryData.SqlSearchParams = New Dictionary(Of String, Object) From {{"UserId", Convert.ToInt32(DirectCast(e.Item, GridDataItem).GetDataKeyValue("UserId"))}}
 
        gridFormView.DataSource = userDetailManager.GetByQuery(queryData)
        gridFormView.DataBind()
    End If
End If

Now I don't have (of course) all the FormView details loaded when the main grid loads as before, but the SQL query is only triggered when I expand a row.
Now the problem is that the FormView is always empty even if the query is triggered correctly. I suspect that this is because the binding here in the Item_Command of the main RadGrid happens too late, when the FormView has already been created and is empty.
I checked this adding this lines to FormView 
<EmptyDataTemplate>
    Form is empty
</EmptyDataTemplate>

How could I solve this, so to trigger the binding only on expanded rows and not on all the grid rows even if they are not expanded?
Wich is the right grid event to check this? I tryed in the ItemDataBound or ItemCreated event but wasn't able to access the FormView inside NestedViewTemplate from there or to access the parent row DataKeyValue for the ID.
Really need some help thanks
0
Massimiliano
Top achievements
Rank 1
answered on 23 Sep 2013, 08:16 PM
Ok I solved. The solution above was correct (almost). The problem was in the DB View I used wich had a wrong join (INNER JOIN instead of LEFT JOIN) so the results where all null (the second DB table is still empty) and FormView displayed empty template.
So to recap.... if you want to fire the query for the FormView only when you expand a detail and not for all the RadGrid rows on page load, this is a way to go.
Another little change to the code is that FormView expects an IList or IEnumerable or such and not a single object of your type of course so I had to add this:
Protected Sub RadGrid1_ItemCommand(ByVal source As Object, ByVal e As GridCommandEventArgs) Handles RadGrid1.ItemCommand
            If e.CommandName = RadGrid.ExpandCollapseCommandName AndAlso TypeOf e.Item Is GridDataItem Then
                '    DirectCast(e.Item, GridDataItem).ChildItem.FindControl("RadGrid1DetailContainer").Visible = Not e.Item.Expanded
                If Not e.Item.Expanded Then
                    Dim gridFormView As FormView = DirectCast(e.Item, GridDataItem).ChildItem.FindControl("RadGrid1DetailContainer").FindControl("RadGrid1DetailMultipage1").FindControl("RadGrid1DetailRadPageView1").FindControl("RadGrid1DetailForm1")
                    Dim primaryKey As Integer = Convert.ToInt32(DirectCast(e.Item, GridDataItem).GetDataKeyValue("UserId"))
 
                    SelectUserDetail(primaryKey, gridFormView)
                End If
            End If
   End Sub
 
        Private Sub SelectUserDetail(primaryKey As Integer, gridFormView As FormView)
            Dim userDetailManager As New EvaVwUserDetailBaseManager
            Dim users As New List(Of EvaVwUserDetailBase)
            Dim queryData As New PagedQuery
 
            ' Query user and add it to IList object for compatibility with FormView
            queryData.SqlSearchParams = New Dictionary(Of String, Object) From {{"UserId", primaryKey}}
            users.Add(userDetailManager.GetByQuery(queryData))
 
            ' Bind to FormView
            gridFormView.DataSource = users
            gridFormView.DataBind()
        End Sub

Hope this can help someone else as well trying to implement this scenario ;)
Tags
Grid
Asked by
Massimiliano
Top achievements
Rank 1
Answers by
Massimiliano
Top achievements
Rank 1
Share this question
or