如何通过其值查找TreeView节点

时间:2011-05-15 09:46:48

标签: wpf xml data-binding

我正在研究家谱应用程序,我计划在XML文档中存储对每个家庭成员的引用。我想阅读这个文档并在我的应用程序中将其显示为树视图,然后使用它在应用程序的其他位置显示一个家庭成员。我需要做的是在节点树中找到一个特定的值(每个成员都有一个唯一的值)。我怎么能找到这个价值?能不能请你帮忙,我对节点编辑很新。 TY。

BTW,下面是我的XAML代码:

        <HierarchicalDataTemplate x:Key="NodeTemplate">
        <HierarchicalDataTemplate.ItemsSource>
            <Binding XPath="child::*" />
        </HierarchicalDataTemplate.ItemsSource>
        <TextBlock Text="{Binding Path=Name}" />
    </HierarchicalDataTemplate>
    <XmlDataProvider x:Key="xmlDataProvider"></XmlDataProvider>
</Window.Resources>
<Grid>
    <TreeView Margin="0,24,0,143"
              Name="treeView1"
              Background="AliceBlue"
              ItemsSource="{Binding Source={StaticResource xmlDataProvider}, XPath=*}"
              ItemTemplate= "{StaticResource NodeTemplate}"/>

2 个答案:

答案 0 :(得分:1)

我假设唯一值是id属性。所以代码看起来如此:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var item = FindItemById(treeView1.Items.Cast<XmlElement>(), "2.1");
        if (item != null)
        {
            //Do something...
            //for example, item.SetAttribute("name", "test");

            //But this code will not work if the item isn't visible
            //var container = treeView1.ItemContainerGenerator.ContainerFromItem(item);
        }
    }

    public XmlElement FindItemById(IEnumerable<XmlElement> items, string id)
    {
        foreach (var item in items)
        {
            if (item.HasAttribute("id") && item.GetAttribute("id") == id)
                return item;
            var childItemsResult = FindItemById(item.ChildNodes.Cast<XmlElement>(), id);
            if (childItemsResult != null)
                return childItemsResult;
        }

        return null;      
    }

如果您的xml文件具有不同的属性作为标识符,请相应地更改此行:item.HasAttribute("id") && item.GetAttribute("id")

最终结果将是XmlElement对象。但是由于树视图项的生成算法,检索容器并不容易。无论如何,如果你有一个特定的问题 - 我可以帮助建立一个正确的架构。

答案 1 :(得分:0)

将可选择的ItemsControl绑定到XmlDataProvider时,SelectedItem包含XmlNode,它是项目的绑定源。如果将其设置为视图的DataContext,则可以显示(或编辑)可从该节点通过XPath选择的任何内容。

因此,在下面的示例中,您可以将其粘贴到Kaxaml中,ContentControl的{​​{1}}绑定到DataContext上的SelectedItem。然后,置于其中的控件可以绑定到可通过XPath找到的任何XML节点。

TreeView

您必须使用<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Page.Resources> <XmlDataProvider x:Key="Data" XPath="/Data"> <x:XData> <Data xmlns=""> <Person Name="Becky"> <Person Name="Stephen"> <Person Name="Tom"/> <Person Name="Susannah"/> </Person> <Person Name="Deborah"> <Person Name="Geoffrey"/> <Person Name="Christopher"/> </Person> </Person> </Data> </x:XData> </XmlDataProvider> </Page.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TreeView x:Name="MyTreeView" ItemsSource="{Binding Source={StaticResource Data}, XPath=*}"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding XPath=*}"> <TextBlock Text="{Binding XPath=@Name}"/> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> <ContentControl Grid.Column="1" DataContext="{Binding ElementName=MyTreeView, Path=SelectedItem}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Label Grid.Row="0">Parent:</Label> <Label Grid.Row="1">Children:</Label> <Label Grid.Column="1" Content="{Binding XPath=@Name}"/> <ListBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding XPath=*}"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@Name}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </ContentControl> </Grid> </Page> 并设置ContentControl。这是这里唯一的实际技巧。你必须这样做的原因:如果你试图绑定一个DataContext,比如说,你最终得到的控件如下:

TextBlock

并且您无法在同一个绑定中使用<TextBlock Text="{Binding ElementName=MyTreeView, Path=SelectedItem, XPath=@Name}"/> Path