在WPF TreeView中设置selectedItem,并将DataContext绑定到XDocument

时间:2018-04-19 11:40:31

标签: c# xml wpf treeview linq-to-xml

我的WPF窗口中有TreeView。 TreeViews DataContext绑定到XDocument。

我正在寻找从后面的代码设置selectedItem。由于例如.ItemContainerGenerator.Items返回的节点是System.Xml.Linq.XElement类型而不是System.Windows.Controls.TreeViewItem,我不能只设置isSelected: - (

有人知道如何解决这个问题吗?

修改: XAML代码:

<Window.Resources>
    <DataTemplate x:Key="AttributeTemplate">
        <StackPanel Orientation="Horizontal"
        Margin="3,0,0,0"
        HorizontalAlignment="Center">
            <TextBlock Text="{Binding Path=Name}"
         Foreground="{StaticResource xmAttributeBrush}" FontFamily="Consolas" FontSize="8pt" />
            <TextBlock Text="=&quot;"
         Foreground="{StaticResource xmlMarkBrush}" FontFamily="Consolas" FontSize="8pt" />
            <TextBlock Text="{Binding Path=Value, Mode=TwoWay}"
         Foreground="{StaticResource xmlValueBrush}" FontFamily="Consolas" FontSize="8pt" />
            <TextBlock Text="&quot;"
         Foreground="{StaticResource xmlMarkBrush}" FontFamily="Consolas" FontSize="8pt" />
        </StackPanel>
    </DataTemplate>

    <HierarchicalDataTemplate x:Key="NodeTemplate">
        <StackPanel Orientation="Horizontal" Focusable="False">
            <TextBlock x:Name="tbName" Text="Root" FontFamily="Consolas" FontSize="8pt" />
            <ItemsControl
        ItemTemplate="{StaticResource AttributeTemplate}" HorizontalAlignment="Center"
        ItemsSource="{Binding Converter={StaticResource AttrConverter}}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </StackPanel>
        <HierarchicalDataTemplate.ItemsSource>
            <Binding Path="Elements" />
        </HierarchicalDataTemplate.ItemsSource>
        <HierarchicalDataTemplate.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=NodeType}" Value="Element" />
                    <Condition Binding="{Binding Path=FirstNode.FirstNode.NodeType}" Value="Text" />
                </MultiDataTrigger.Conditions>
                <Setter TargetName="tbName" Property="Text" >
                    <Setter.Value>
                        <Binding Path="Name" />
                    </Setter.Value>
                </Setter>
                <Setter TargetName="tbName" Property="ToolTip">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource MultiString2StringKonverter}">
                            <Binding Path="FirstNode.Value" />
                            <Binding Path="FirstNode.NextNode.Value" />
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </MultiDataTrigger>
            <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
                <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Name}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=FirstNode.NodeType}" Value="Text">
                <Setter TargetName="tbName" Property="Text">
                    <Setter.Value>
                        <MultiBinding StringFormat="{}{0} = {1}">
                            <Binding Path="Name"/>
                            <Binding Path="FirstNode.Value"/>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </HierarchicalDataTemplate.Triggers>
    </HierarchicalDataTemplate>
</Window.Resources>

<TreeView x:Name="LizenzAnsicht"
      ItemsSource="{Binding Path=Root.Elements, UpdateSourceTrigger=PropertyChanged}"
      ItemTemplate="{StaticResource ResourceKey=NodeTemplate}"
      />

背后的代码: ...

LizenzAnsicht.DataContext = XDocument.Load(<Path to XML-File>);

1 个答案:

答案 0 :(得分:0)

在这个周末睡了一觉后,我自己找到了一个答案。还有一些问题只是返回类型。

解决方法是获取Item的匹配ItemContainer。这个Container的类型是TreeViewItem,我可以在其中设置isSelected等。

作为一个例子,大部分时间都是为了理解,我给出一个。以下函数将在TreeView对象中搜索XML节点,并返回包含匹配节点的TreeViewItem。如果未找到匹配,则返回null。 匹配节点已扩展。 XML在System.Xml.linq.XDocument中处理,该文件绑定到System.Windows.Controls.TreeView DataContext。 调用函数时,TreeView设置为ic。

public static TreeViewItem SearchNodeInTreeView(ItemsControl ic, XElement NodeDescription, string indent = "")
{
    TreeViewItem ret = null;
    foreach (object o in ic.Items)
    {
        if (o is XElement)
        {
            var x = ic.ItemContainerGenerator.ContainerFromItem(o);
            if (XNode.DeepEquals((o as XElement), NodeDescription))
            {
                ret = x as TreeViewItem;
            }
            else if ((o as XElement).HasElements){
                if (x != null)
                {
                    bool expanded = (x as TreeViewItem).IsExpanded;
                    (x as TreeViewItem).IsExpanded = true;
                    (x as TreeViewItem).UpdateLayout();
                    ret = SearchNodeInTreeView (x as TreeViewItem, NodeDescription, indent + "  ");
                    if (ret == null)
                    {
                        (x as TreeViewItem).IsExpanded = expanded;
                        (x as TreeViewItem).UpdateLayout();
                    }
                }
            }
        }
        if (ret != null)
        {
            break;
        }
    }
    return ret;
}

我希望我可以帮助任何人。