I’m making an asp.page that will display hierarchical information about company assets.
To grab the data I used a lambda expression:
FASAssetInfoDataContext fasInfo = new FASAssetInfoDataContext();
var data = from g in fasInfo.Asset_Informations
where g.Department.Substring(0, 3) == p
select g;
Dictionary<string, Dictionary<string, List<info>>> branch = data.GroupBy(e => e.Location)
.ToDictionary(g => g.Key,
g => g.GroupBy(gl => gl.G_L_Asset_Acct_No)
.ToDictionary(gl => gl.Key,
gl => gl.Select(s => new info
{
acqDate = s.Acquisition_Date,
asstNo = s.Co_Asset_Number,
classInfo = s.Class,
description = s.Description,
mfgSerialNo = s.Mfg_Serial_No,
deprThisRun = s.Depr_This_Run__Int_,
AcqValue = s.Acquisition_Value__Int_,
currentAccDepr = s.Current_Accum_Depr__Int_,
estLife = s.Est_Life__YYMM___Int_,
inServiceDate = s.Placed_In_Service_Date__Int_,
netBookValue = s.Current_Net_Book_Value__Int_,
oldAcqValue = s.Acquisition_Value__Tax_
}).ToList()));
So I now have a nested set of dictionaries with a list of information at the end. My question is how do I best display this information on the page itself? I can get the first level but have been struggling to get the nested repeater to function properly. If there is a better control to use I’m all ears 🙂
Thanks,
Marco
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
If you do indeed need to use nested repeaters, its possible, but getting it working isn’t particularly obvious. The following would work (simplified for brevity):
<asp:Repeater id="level1" OnItemDataBound="level1_ItemDataBound" ...>
<ItemTemplate>
<asp:Repeater id="level2" OnItemDataBound="level2_ItemDataBound" ...>
<ItemTemplate>
<asp:Repeater id="level3" OnItemDataBound="level3_ItemDataBound" ...>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
Dictionary<string, Dictionary<string, List<info>>> branch = ...;
level1.DataSource = branch;
level1.DataBind();
}
protected void level1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Dictionary<string, List<info>> data = (Dictionary<string, List<info>>)e.Item.DataItem;
Repeater level2 = e.Item.FindControl("level2") as Repeater;
level2.DataSource = data;
level2.DataBind();
}
protected void level2_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
List<info> data = (List<info>)e.Item.DataItem;
Repeater level3 = e.Item.FindControl("level3") as Repeater;
level3.DataSource = data;
level3.DataBind();
}
protected void level3_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// Bind properties from info elements in List<info> here
}
Method 2
There’s an nicer way of doing this without any ItemDataBound events. For simplicity let’s assume two level of repeaters.
<asp:Repeater id="level1" >
<ItemTemplate>
<asp:Repeater id="level2"
DataSource='<%# ((System.Collections.Generic.KeyValuePair<string,System.Collections.Generic.List<string>>)Container.DataItem).Value %>' >
<ItemTemplate>
<%# Container.DataItem %>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
I usually prefer this way, since for some reason I hate ItemDataBound events 🙂
Method 3
asp:TreeView? Not sure how it will handle the nested data set but it’s designed to display it.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0