The MasterTableView.NestedViewTemplate property does not seem to be stored in ViewState so I'm currently trying to set the MasterTableView.NestedViewTemplate in the PreRender with no success.
Does anyone have an idea how this might be possible?
PS. For efficiency my child data needs to only be databound when expanded.
2 Answers, 1 is accepted
You can access the GridNestedViewItem and then hide the various sections in the NesterdViewTemplate as shown in the example below:
aspx:
| <NestedViewTemplate> |
| <asp:Panel ID="Panel1" runat="server"> |
| Section 1 |
| </asp:Panel> |
| <asp:Panel ID="Panel2" runat="server"> |
| Section 2 |
| </asp:Panel> |
| </NestedViewTemplate> |
c#:
| protected void RadGrid1_PreRender(object sender, EventArgs e) |
| { |
| foreach (GridDataItem dataItem in RadGrid1.Items) |
| { |
| GridNestedViewItem nestedItem = (GridNestedViewItem)dataItem.ChildItem; // to access the nestedviewitem |
| // if(condition based on selection) |
| ((Panel)nestedItem.FindControl("Panel2")).Visible = false; // to access a control in the mnested view |
| // else |
| // ((Panel)nestedItem.FindControl("Panel2")).Visible = true; |
| } |
| } |
Thanks
Princy.
I can't simply show/hide sections defined at design time because the content of the NestedView needs to be far more dynamic than that. Think of it as the user adding any number of modules each with there own set of options.
The good news however is that I have solved my own problem. I was going to attach a sample app that shows what I have done but I can't attach zip files. I was then going to attach a screen shot of the app but this does not seem to be working for some reason.
Basicly the app consists of two RadLists the left one with a list of components that can the included in the NestedView. Items can the transefered to the right hand list (TransferMode=Copy) so the some components can be added multiple times. Once the use clicks the apply button these settings are applyed to the NesterView.
The aspx I use is as follows, Note the NestedView template:
| <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Default" %> |
| <%@ Register TagPrefix="lib" Namespace="DynamicNestedViewTestLibrary.Controls" Assembly="DynamicNestedViewTestLibrary" %> |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml"> |
| <head runat="server"> |
| <title></title> |
| <telerik:RadStyleSheetManager id="RadStyleSheetManager1" runat="server" /> |
| </head> |
| <body> |
| <form id="form1" runat="server"> |
| <telerik:RadScriptManager ID="RadScriptManager1" runat="server"> |
| <Scripts> |
| <asp:ScriptReference Assembly="Telerik.Web.UI, Version=2009.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4" Name="Telerik.Web.UI.Common.Core.js" /> |
| <asp:ScriptReference Assembly="Telerik.Web.UI, Version=2009.2.826.35, Culture=neutral, PublicKeyToken=121fae78165ba3d4" Name="Telerik.Web.UI.Common.jQuery.js" /> |
| </Scripts> |
| </telerik:RadScriptManager> |
| <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server"> |
| </telerik:RadAjaxManager> |
| <telerik:RadSkinManager ID="RadSkinManager1" Runat="server" Skin="Sunset"> |
| </telerik:RadSkinManager> |
| <div> |
| <telerik:RadListBox ID="lstOption" TransferToID="lstShown" TransferMode="Copy" AllowTransfer="true" AllowTransferDuplicates="true" AllowTransferOnDoubleClick="true" Height="150" runat="server"> |
| <Items> |
| <telerik:RadListBoxItem Value="Note_Add" Text="Note Add" /> |
| <telerik:RadListBoxItem Value="Note_Sub" Text="Note Sub" /> |
| <telerik:RadListBoxItem Value="Note_Move" Text="Note Move" /> |
| <telerik:RadListBoxItem Value="Pet_Cat" Text="Pet cat" /> |
| <telerik:RadListBoxItem Value="Pet_Dog" Text="Pet dog" /> |
| <telerik:RadListBoxItem Value="Pet_Bird" Text="Pet bird" /> |
| </Items> |
| </telerik:RadListBox> |
| <telerik:RadListBox ID="lstShown" AllowDelete="true" AllowReorder="true" Height="150" runat="server"> |
| </telerik:RadListBox> |
| <asp:Button ID="btnApply" Text="Apply" OnClick="btnApply_Click" runat="server" /> |
| <asp:Button ID="btnClear" Text="Clear" OnClick="btnClear_Click" runat="server" /> |
| <br /> |
| <br /> |
| <asp:LinkButton ID="lnkExpandAll" Text="Expand All" OnClick="lnkExpandAll_Click" runat="server" /> |
| <asp:LinkButton ID="lnkCollapseAll" Text="Collapse All" OnClick="lnkCollapseAll_Click" runat="server" /> |
| <telerik:RadGrid ID="MyGrid" AllowPaging="true" OnPreRender="MyGrid_PreRender" OnNeedDataSource="MyGrid_NeedDataSource" runat="server"> |
| <MasterTableView DataKeyNames="Id" HierarchyLoadMode="ServerOnDemand" AllowSorting="true" AutoGenerateColumns="false" > |
| <GroupByExpressions> |
| <telerik:GridGroupByExpression> |
| <GroupByFields> |
| <telerik:GridGroupByField FieldName="Gender" /> |
| </GroupByFields> |
| <SelectFields> |
| <telerik:GridGroupByField FieldName="Gender" /> |
| </SelectFields> |
| </telerik:GridGroupByExpression> |
| </GroupByExpressions> |
| <Columns> |
| <telerik:GridBoundColumn UniqueName="Id" DataField="Id" HeaderText="Id" /> |
| <telerik:GridBoundColumn UniqueName="Name" DataField="Name" HeaderText="Name" /> |
| <telerik:GridBoundColumn UniqueName="Age" DataField="Age" HeaderText="Age" /> |
| <telerik:GridBoundColumn UniqueName="Gender" DataField="Gender" HeaderText="Gender" /> |
| </Columns> |
| <NestedViewTemplate> |
| <lib:Details ID="ctlDetails" runat="server" /> |
| </NestedViewTemplate> |
| </MasterTableView> |
| </telerik:RadGrid> |
| </div> |
| </form> |
| </body> |
| </html> |
The Details control in the NesterView template has a settings property (csv of the items to show) and addes more custom controls to its self depending the settings:
| public class Details : System.Web.UI.Control |
| { |
| public string Settings |
| { |
| get { return (string)ViewState["Settings"]; } |
| set |
| { |
| if (Settings != value) |
| { |
| ViewState["Settings"] = value; |
| RenderMe(); |
| } |
| } |
| } |
| public Details() |
| { |
| } |
| protected override void OnLoad(EventArgs e) |
| { |
| base.OnLoad(e); |
| EnsureChildControls(); |
| } |
| protected override void CreateChildControls() |
| { |
| base.CreateChildControls(); |
| RenderMe(); |
| } |
| public void RenderMe() |
| { |
| this.Controls.Clear(); |
| if (!string.IsNullOrEmpty(Settings)) |
| { |
| int count = 0; |
| foreach (string itm in Settings.Split(","[0])) |
| { |
| count++; |
| if (!string.IsNullOrEmpty(itm)) |
| { |
| if (itm.StartsWith("Note_")) |
| { |
| DetailItem_Note note = new DetailItem_Note(); |
| note.ID = "note_" + count; |
| note.ItemSettings = itm.Remove(0, 5); |
| this.Controls.Add(note); |
| } |
| else if (itm.StartsWith("Pet_")) |
| { |
| DetailItem_Pet pet = new DetailItem_Pet(); |
| pet.ID = "pet_" + count; |
| pet.ItemSettings = itm.Remove(0, 4); |
| this.Controls.Add(pet); |
| } |
| this.Controls.Add(new LiteralControl("<br />")); |
| } |
| } |
| } |
| } |
| } |
| public class DetailItem_Base : System.Web.UI.Control |
| { |
| public string ItemSettings |
| { |
| get |
| { |
| return (string)ViewState["ItemSettings"]; |
| } |
| set |
| { |
| ViewState["ItemSettings"] = value; |
| } |
| } |
| protected override void OnLoad(EventArgs e) |
| { |
| base.OnLoad(e); |
| EnsureChildControls(); |
| } |
| }//class |
| public class DetailItem_Note : DetailItem_Base |
| { |
| private Label lbl; |
| private Button btn; |
| private TextBox txt; |
| protected override void CreateChildControls() |
| { |
| base.CreateChildControls(); |
| lbl = new Label(); |
| lbl.ID = "lbl_" + this.ID; |
| lbl.Text = "0"; |
| this.Controls.Add(lbl); |
| btn = new Button(); |
| btn.ID = "btn_" + this.ID; |
| btn.Click += btn_Click; |
| switch (this.ItemSettings) |
| { |
| case "Add": |
| btn.Text = "Add"; |
| break; |
| case "Sub": |
| btn.Text = "Subtract"; |
| break; |
| case "Move": |
| txt = new TextBox(); |
| txt.ID = "txt_" + this.ID; |
| txt.Width = 75; |
| this.Controls.Add(txt); |
| btn.Text = "Move"; |
| break; |
| } |
| this.Controls.Add(btn); |
| } |
| private void btn_Click(object sender, EventArgs e) |
| { |
| switch (this.ItemSettings) |
| { |
| case "Add": |
| lbl.Text = (int.Parse(lbl.Text) + 1).ToString(); |
| break; |
| case "Sub": |
| lbl.Text = (int.Parse(lbl.Text) - 1).ToString(); |
| break; |
| case "Move": |
| lbl.Text = txt.Text; |
| txt.Text = string.Empty; |
| break; |
| } |
| } |
| } |
| public class DetailItem_Pet : DetailItem_Base |
| { |
| protected override void CreateChildControls() |
| { |
| base.CreateChildControls(); |
| if (ViewState["DataFromDB"] == null) |
| { |
| // Simulate getting data |
| System.Threading.Thread.Sleep(1000); |
| switch (this.ItemSettings) |
| { |
| case "Cat": |
| ViewState["DataFromDB"] = "Cats eat native birds, bad cats."; |
| break; |
| case "Dog": |
| ViewState["DataFromDB"] = "Dogs can NOT climb trees."; |
| break; |
| case "Bird": |
| ViewState["DataFromDB"] = "Birds saw but not through wood!"; |
| break; |
| } |
| } |
| this.Controls.Add(new LiteralControl((string)ViewState["DataFromDB"])); |
| } |
| } |
| public partial class Default : System.Web.UI.Page |
| { |
| protected void Page_Load(object sender, EventArgs e) |
| { |
| if (!IsPostBack) |
| { |
| btnClear_Click(this, EventArgs.Empty); |
| MyGrid.DataSource = People.GetTestData(); |
| MyGrid.DataBind(); |
| } |
| } |
| protected void MyGrid_NeedDataSource(object sender, GridNeedDataSourceEventArgs e) |
| { |
| MyGrid.DataSource = People.GetTestData(); |
| } |
| protected void MyGrid_PreRender(object sender, EventArgs e) |
| { |
| foreach (GridDataItem item in MyGrid.MasterTableView.Items) |
| { |
| DynamicNestedViewTestLibrary.Controls.Details ctlDetails = (DynamicNestedViewTestLibrary.Controls.Details)item.ChildItem.FindControl("ctlDetails"); |
| if (item.Expanded) |
| { |
| string strCurrentSettings = (string)(ViewState["CurrentSettings"] ?? string.Empty); |
| //if (string.IsNullOrEmpty(strCurrentSettings)) |
| //item.Expanded = false; |
| //else |
| //{ |
| ctlDetails.Settings = strCurrentSettings; |
| //} |
| } |
| else |
| ctlDetails.Settings = null; |
| } |
| } |
| protected void btnApply_Click(object sender, EventArgs e) |
| { |
| string strNewSettings = string.Empty; |
| foreach (RadListBoxItem itm in lstShown.Items) |
| { |
| strNewSettings += "," + itm.Value; |
| } |
| ViewState["CurrentSettings"] = strNewSettings; |
| MyGrid.MasterTableView.ExpandCollapseColumn.Display = true; |
| } |
| protected void btnClear_Click(object sender, EventArgs e) |
| { |
| lstShown.Items.Clear(); |
| ViewState["CurrentSettings"] = string.Empty; |
| MyGrid.MasterTableView.ExpandCollapseColumn.Display = false; |
| // This could be replaced by un-expanding in MyGrid_PreRender() (see |
| //commented out code). However this better fits my full example. |
| MyGrid.Rebind(); |
| } |
| protected void lnkExpandAll_Click(object sender, EventArgs e) |
| { |
| foreach (GridDataItem itm in MyGrid.MasterTableView.Items) |
| itm.Expanded = itm.Visible; |
| } |
| protected void lnkCollapseAll_Click(object sender, EventArgs e) |
| { |
| foreach (GridDataItem itm in MyGrid.MasterTableView.Items) |
| itm.Expanded = false; |
| } |
| }//class |
The only other component I used was a People class to simulate the web service data I have in my full app:
| public class People |
| { |
| public int Id { get; set; } |
| public string Name { get; set; } |
| public int Age { get; set; } |
| public string Gender { get; set; } |
| /// <summary> |
| /// Get some test data for a grid |
| /// </summary> |
| /// <returns></returns> |
| public static People[] GetTestData() |
| { |
| People[] Out = new People[13]; |
| Out[0] = new People() { Id = 0, Name = "Jill", Age = 34, Gender = "F" }; |
| Out[1] = new People() { Id = 1, Name = "Bob", Age = 23, Gender = "M" }; |
| Out[2] = new People() { Id = 2, Name = "Max", Age = 8, Gender = "M" }; |
| Out[3] = new People() { Id = 3, Name = "Kate", Age = 63, Gender = "F" }; |
| Out[4] = new People() { Id = 4, Name = "John", Age = 93, Gender = "M" }; |
| Out[5] = new People() { Id = 5, Name = "Jo", Age = 46, Gender = "F" }; |
| Out[6] = new People() { Id = 6, Name = "Aaron", Age = 2, Gender = "M" }; |
| Out[7] = new People() { Id = 7, Name = "Jen", Age = 24, Gender = "F" }; |
| Out[8] = new People() { Id = 8, Name = "Penny", Age = 76, Gender = "F" }; |
| Out[9] = new People() { Id = 9, Name = "Charlie", Age = 45, Gender = "M" }; |
| Out[10] = new People() { Id = 10, Name = "Simon", Age = 54, Gender = "M" }; |
| Out[11] = new People() { Id = 11, Name = "Lex", Age = 13, Gender = "F" }; |
| Out[12] = new People() { Id = 12, Name = "Anna", Age = 24, Gender = "F" }; |
| return Out; |
| } |
| }//class |