tags:

views:

50

answers:

4

TreeView:

   -MainNode
      -node0
          data01
          -data02
             data021
             data022
          data03
      -node1
          data11
      -node2
          data21

Event SelectedChange;

As the choice of a node containing child nodes to get the final data?

For example: selected node node0 receive data (data01, data021, data022, data03)

+1  A: 

I'd use a simple recursion to get what you want. Pseudo code below:

private List recursive_method(Node selectedNode) {

List<Node> data = new List<Node>();

foreach(child in nodelist.Children) {
    data.add(child);
    List<Node> children = recursive_method(child);
    if(children != null) data.addRange(children);
}

return data;

}

dineth
+1  A: 

I am assuming what you what is this: On click of the top level nodes (node0, node1, node2), I want to get all the children data nodes in the tree.

If this is what you need, here's the code:

<Window x:Class="WpfApplication2.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="myTreeView" Height="271" HorizontalAlignment="Left" Margin="47,12,0,0" VerticalAlignment="Top" Width="236" SelectedItemChanged="myTreeView_SelectedItemChanged">
        <TreeViewItem Header="node0" >
            <TreeViewItem Header="data01" />
            <TreeViewItem Header="data02" >
                <TreeViewItem Header="data021" />
                <TreeViewItem Header="data022" />
            </TreeViewItem>
            <TreeViewItem Header="data03" />
        </TreeViewItem>
        <TreeViewItem Header="node1" >
            <TreeViewItem Header="data11" />
        </TreeViewItem>
        <TreeViewItem Header="node2" >
            <TreeViewItem Header="data21" />
        </TreeViewItem>
    </TreeView>
</Grid>
</Window>

And the cs code behind to handle SelectedItemChanged event will look like this

    private void myTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        foreach (TreeViewItem dataNode in ((TreeViewItem)e.NewValue).Items)
        {
            TraverseChildrenData(dataNode);
        }
    }

    public void TraverseChildrenData(TreeViewItem treeViewItem)
    {
        //do whatever you want to do with child data item here..   
        MessageBox.Show(treeViewItem.Header.ToString());

        foreach (TreeViewItem child in treeViewItem.Items)
        {
            TraverseChildrenData(child);
        }
    }
Souvik
Note that this won't work if you bind to the ItemsSource.
Bubblewrap
I tried binding the TreeView's ItemSource to XML data and it works fine. I have added one more answer which uses ItemsSource. Please let me know if that looks good or if I have missed something
Souvik
A: 

Here's a changed version of my earlier answer. This one uses TreeView's ItemsSource to bind data

XML data:

<data>
  <datanode Header="node0" >
    <datanode Header="data01" />
    <datanode Header="data02" >
      <datanode Header="data021" />
      <datanode Header="data022" />
    </datanode>
    <datanode Header="data03" />
  </datanode>
  <datanode Header="node1" >
    <datanode Header="data11" />
  </datanode>
  <datanode Header="node2" >
    <datanode Header="data21" />
  </datanode>
</data>

XAML:

<Grid>
    <Grid.DataContext>
        <XmlDataProvider Source="Data.xml" XPath="/data/datanode" />
    </Grid.DataContext>
    <TreeView x:Name="myTreeView" Height="271" HorizontalAlignment="Left" Margin="47,12,0,0" VerticalAlignment="Top" Width="236" SelectedItemChanged="myTreeView_SelectedItemChanged" ItemsSource="{Binding}" >
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding}" >
                    <TextBlock Text="{Binding XPath=@Header}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Grid>

CS:

    private void myTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        foreach (XmlElement dataNode in ((XmlElement)e.NewValue).ChildNodes)
        {
            TraverseChildrenData(dataNode);
        }
    }

    public void TraverseChildrenData(XmlElement treeViewItem)
    {
        //do whatever you want to do with child data item here..   
        MessageBox.Show(treeViewItem.Attributes["Header"].Value);

        foreach (XmlElement child in treeViewItem.ChildNodes)
        {
            TraverseChildrenData(child);
        }
    }
Souvik
+1  A: 

To get an IEnumerable from a node structure i found this article really helpful

http://www.claassen.net/geek/blog/2009/06/searching-tree-of-objects-with-linq.html

It uses extension methods and you get all the goods of reusability and delayed execution.

Usage example:

IEnumerable<XmlElement> nodes = treeViewItem.AsBreadthFirstEnumerable(x => x.ChildNodes);
MrDosu