locked
How to: Binding Treeview to XML based on Element's value RRS feed

  • 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.eu
    • Proposed as answer by Jie Bao Tuesday, March 15, 2011 9:31 AM
    • Marked as answer by Jie Bao Monday, March 21, 2011 8:37 AM
    Monday, 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.eu
    • Proposed as answer by Jie Bao Tuesday, March 15, 2011 9:31 AM
    • Marked as answer by Jie Bao Monday, March 21, 2011 8:37 AM
    Monday, 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.eu
    • Proposed as answer by Jie Bao Tuesday, March 15, 2011 9:31 AM
    • Marked as answer by Jie Bao Monday, March 21, 2011 8:37 AM
    Monday, 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.eu
    • Proposed as answer by Jie Bao Tuesday, March 15, 2011 9:31 AM
    • Marked as answer by Jie Bao Monday, March 21, 2011 8:37 AM
    Monday, March 14, 2011 11:43 AM