Answered by:
How to: Binding Treeview to XML based on Element's value

Question
-
I have a list of data that comes in in XML format (I can easily parse it to objects, but I still cant figure out how to bind), and I need help with binding based on value in XML...
Sample Data:
<CustomerRet>
<ListID>1</ListID>
<TimeCreated>2010-09-18T09:18:16-05:00</TimeCreated>
<TimeModified>2011-03-13T23:12:50-05:00</TimeModified>
<Name>Alex</Name>
<FullName>Alex</FullName>
<IsActive>true</IsActive>
<Sublevel>0</Sublevel>
<CustomerRet>
<CustomerRet>
<ListID>2</ListID>
<TimeCreated>2010-09-18T09:18:16-05:00</TimeCreated>
<TimeModified>2011-03-13T23:12:50-05:00</TimeModified>
<Name>Steven</Name>
<IsActive>true</IsActive>
<Sublevel>1</Sublevel>
<Parent>
<ListID>1</ListID>
<FullName>Alex:Steven</FullName>
</Parent>
<CustomerRet>
<CustomerRet>
<ListID>3</ListID>
<TimeCreated>2010-09-18T09:18:16-05:00</TimeCreated>
<TimeModified>2011-03-13T23:12:50-05:00</TimeModified>
<Name>John</Name>
<IsActive>true</IsActive>
<Sublevel>2</Sublevel>
<Parent>
<ListID>2</ListID>
<FullName>Alex:Steven:John</FullName>
</Parent>
<CustomerRet>Desired Treeview should be some thing like this:
Alex
Steven
John
Customer (Alex)
Sub-cust(Steven)
Sub-sub-cust(John)
Also, Some customers have only 1 or no levels, and the number of levels can go upto 5.
Thanks in advance
Monday, March 14, 2011 3:45 AM
Answers
-
The problem here is that you have a planified hierarchical list. I'd say the best approach would be to parse your XML into a class of your own and then use a HierarchicalDataTemplate on the TreeView.
Bigsby, Lisboa, Portugal
O que for, quando for, é que será o que é...
Wenn ist das Nunstruck git und Slotermeyer? Ja! ... Beiherhund das Oder die Flipperwaldt gersput!
http://bigsby.euMonday, March 14, 2011 11:06 AM -
This might help get you started.
CustomerRet.cs:
using System; using System.Collections.Generic; using System.Linq; namespace HierarchicalXML { public class CustomerRet { public int ListID { get; set; } public DateTime TimeCreated { get; set; } public DateTime TimeModified { get; set; } public string Name { get; set; } public string FullName { get; set; } public bool IsActive { get; set; } public int Sublevel { get; set; } public ParentRef Parent { get; set; } private List<CustomerRet> _subCustomers; public List<CustomerRet> SubCustomers { get { return _subCustomers ?? (_subCustomers = new List<CustomerRet>()); } } public static List<CustomerRet> HierarchizeList(List<CustomerRet> planified) { var result = new List<CustomerRet>(); var enumerator = planified.GetEnumerator(); foreach (var customer in planified.Where(plan => plan.Sublevel == 0)) { AddChildren(customer, planified); result.Add(customer); } return result; } private static void AddChildren(CustomerRet parent, IEnumerable<CustomerRet> planified) { foreach (var child in planified.Where(item => null != item.Parent && item.Parent.ListID == parent.ListID)) { parent.SubCustomers.Add(child); AddChildren(child, planified); } } } public class ParentRef { public int ListID { get; set; } public string FullName { get; set; } } }
MainWindow.xaml.cs
using System.Collections.Generic; using System.Windows; using System.IO; using System.Xml.Serialization; namespace HierarchicalXML { public partial class MainWindow : Window { // I put your xml in a file private static string _filePath = @"..\List.xml"; public MainWindow() { InitializeComponent(); var fileStream = File.OpenRead(_filePath); var serializer = new XmlSerializer(typeof(List<CustomerRet>), null, new[] { typeof(ParentRef) }, new XmlRootAttribute("Customers"), ""); var planifiedList = serializer.Deserialize(fileStream); treeView.ItemsSource = CustomerRet.HierarchizeList((List<CustomerRet>)planifiedList); } } }
And, then, the binding and templating.
MainWindow.xaml
<Window x:Class="HierarchicalXML.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <TreeView x:Name="treeView"> <ItemsControl.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding SubCustomers}"> <TextBlock Text="{Binding Name}"/> </HierarchicalDataTemplate> </ItemsControl.ItemTemplate> </TreeView> </Grid> </Window>
Bigsby, Lisboa, Portugal
O que for, quando for, é que será o que é...
Wenn ist das Nunstruck git und Slotermeyer? Ja! ... Beiherhund das Oder die Flipperwaldt gersput!
http://bigsby.euMonday, March 14, 2011 11:43 AM
All replies
-
The problem here is that you have a planified hierarchical list. I'd say the best approach would be to parse your XML into a class of your own and then use a HierarchicalDataTemplate on the TreeView.
Bigsby, Lisboa, Portugal
O que for, quando for, é que será o que é...
Wenn ist das Nunstruck git und Slotermeyer? Ja! ... Beiherhund das Oder die Flipperwaldt gersput!
http://bigsby.euMonday, March 14, 2011 11:06 AM -
This might help get you started.
CustomerRet.cs:
using System; using System.Collections.Generic; using System.Linq; namespace HierarchicalXML { public class CustomerRet { public int ListID { get; set; } public DateTime TimeCreated { get; set; } public DateTime TimeModified { get; set; } public string Name { get; set; } public string FullName { get; set; } public bool IsActive { get; set; } public int Sublevel { get; set; } public ParentRef Parent { get; set; } private List<CustomerRet> _subCustomers; public List<CustomerRet> SubCustomers { get { return _subCustomers ?? (_subCustomers = new List<CustomerRet>()); } } public static List<CustomerRet> HierarchizeList(List<CustomerRet> planified) { var result = new List<CustomerRet>(); var enumerator = planified.GetEnumerator(); foreach (var customer in planified.Where(plan => plan.Sublevel == 0)) { AddChildren(customer, planified); result.Add(customer); } return result; } private static void AddChildren(CustomerRet parent, IEnumerable<CustomerRet> planified) { foreach (var child in planified.Where(item => null != item.Parent && item.Parent.ListID == parent.ListID)) { parent.SubCustomers.Add(child); AddChildren(child, planified); } } } public class ParentRef { public int ListID { get; set; } public string FullName { get; set; } } }
MainWindow.xaml.cs
using System.Collections.Generic; using System.Windows; using System.IO; using System.Xml.Serialization; namespace HierarchicalXML { public partial class MainWindow : Window { // I put your xml in a file private static string _filePath = @"..\List.xml"; public MainWindow() { InitializeComponent(); var fileStream = File.OpenRead(_filePath); var serializer = new XmlSerializer(typeof(List<CustomerRet>), null, new[] { typeof(ParentRef) }, new XmlRootAttribute("Customers"), ""); var planifiedList = serializer.Deserialize(fileStream); treeView.ItemsSource = CustomerRet.HierarchizeList((List<CustomerRet>)planifiedList); } } }
And, then, the binding and templating.
MainWindow.xaml
<Window x:Class="HierarchicalXML.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <TreeView x:Name="treeView"> <ItemsControl.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding SubCustomers}"> <TextBlock Text="{Binding Name}"/> </HierarchicalDataTemplate> </ItemsControl.ItemTemplate> </TreeView> </Grid> </Window>
Bigsby, Lisboa, Portugal
O que for, quando for, é que será o que é...
Wenn ist das Nunstruck git und Slotermeyer? Ja! ... Beiherhund das Oder die Flipperwaldt gersput!
http://bigsby.euMonday, March 14, 2011 11:43 AM