Reg: Binding an XML file to TreeView using Silver Light

May 24 2010 7:37 AM

Hi,
I am having an XML file, the entire content of an XML file is in XDocument now i want to bind it a TreeView.   Suggest a way which we can directly assign as a source to a TreeView and then DataBind().  But i dont want to use the below mentioned way:
XML: (Data.xml)
<categories>
  <category name="Microsoft" url="http://www.microsoft.com">
    <children>
      <category name="MSDN" url="http://msdn.microsoft.com">
        <children />
      </category>
      <category name="Silverlight" url="http://www.silverlight.net">
        <children>
          <category name="Forums" url="http://silverlight.net/forums">
            <children />
          </category>
        </children>
      </category>
    </children>
  </category>
  <category name="Search Engines" url="">
    <children>
      <category name="Live" url="http://www.live.com">
        <children />
      </category>
      <category name="Google" url="http://www.google.com">
        <children />
      </category>
      <category name="Yahoo" url="http://www.yahoo.com">
        <children />
      </category>
    </children>
  </category>
</categories>
XAML:
        <y:TreeView x:Name="listCategories" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" SelectedItemChanged="listCategories_SelectedItemChanged">
            <y:TreeView.ItemTemplate>
                <y:HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <TextBlock Margin="0" Text="{Binding Name, Mode=OneWay}" FontSize="12" />
                </y:HierarchicalDataTemplate>
            </y:TreeView.ItemTemplate>
        </y:TreeView>
C#:
    public class Category
    {
        public string Name              { get; set; }
        public List<Category> Children  { get; set; }
        public Uri Url                  { get; set; }
    }
    public partial class Page : UserControl
    {
        private List<Category> Categories { get; set; }
        public Page()
        {
            InitializeComponent();
            // Populate categories from local data source
            XElement root = XElement.Load("Data.xml");
            Categories = (from c in root.Elements("category")
                          select new Category
                          {
                              Name = (string)c.Attribute("name"),
                              Children = LoadData(c),
                              Url = ((string)c.Attribute("url") == "") ? null : new Uri((string)c.Attribute("url"), UriKind.RelativeOrAbsolute)
                          }).ToList();
            // Update categories' data
            listCategories.ItemsSource = Categories;              
        }
        private List<Category> LoadData(XElement root)
        {
            if (root == null)
                return null;
            // Load children data
            return (from c in root.Element("children").Elements("category")
                    select new Category
                    {
                        //Create source
                        Name = (string)c.Attribute("name"),
                        Children = c.Element("children") == null ? null : LoadData(c),
                        Url = ((string)c.Attribute("url") == "") ? null : new Uri((string)c.Attribute("url"), UriKind.RelativeOrAbsolute)
                    }).ToList();
        }
        private void listCategories_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            Category category = (Category)listCategories.SelectedItem;
            // Validate category (some categories don't have files)           
            if (category == null || category.Url == null)
                return;
            HtmlPage.Window.Navigate(category.Url, "_blank");
        }
    }
 
Thanks in Advance.