【问题标题】:Set selectedItem in WPF TreeView with DataContext bound to XDocument在 WPF TreeView 中设置 selectedItem,并将 DataContext 绑定到 XDocument
【发布时间】:2018-04-19 11:40:31
【问题描述】:

我的 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>);

【问题讨论】:

  • 看起来您正在返回项目而不是树节点:ItemContainerGenerator.Items。为什么不返回 ItemContainerGenerator
  • 用你的代码改进你的问题。那太棒了!
  • @jdweng:我认为 ItemContainerGenerator 不会给我一个具有所需属性或方法的对象。我想我需要遍历 TreeView 的所有项目,直到找到正确的项目......这个需要作为具有 isEnabled 属性的对象......

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


【解决方案1】:

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

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

作为一个例子在大多数情况下更容易理解,我举一个例子。以下函数将在 TreeView- 对象中搜索 XML- 节点并返回包含匹配节点的 TreeViewItem。如果未找到匹配项,则返回 null。 匹配节点被展开。 XML 在绑定到 System.Windows.Controls.TreeView DataContext 的 System.Xml.linq.XDocument 中处理。 调用函数时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;
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 2013-02-22
    • 2010-09-19
    • 2011-02-09
    • 2012-06-19
    • 1970-01-01
    • 2023-04-10
    相关资源
    最近更新 更多