wpf如何将一个TreeView绑定到另一个TreeView

时间:2018-09-06 09:31:28

标签: c# wpf treeview

我正在尝试将TreeView t2绑定到xaml中的TreeView t1,如下所示:

<Window x:Class="WpfApp2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp2"
    mc:Ignorable="d"
    Title="MainWindow" Height="620" Width="600">
<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type TreeViewItem}" ItemsSource="{Binding Items}">
        <StackPanel Orientation="Horizontal" >
            <TextBlock Background="AliceBlue" Text="{Binding Path=Header, Mode=TwoWay}" Width="220"/>
        </StackPanel>
    </HierarchicalDataTemplate>
</Window.Resources>
<StackPanel>
    <TreeView x:Name="t1">
        <TreeView.Items>
            <TreeViewItem Header="a"></TreeViewItem>
            <TreeViewItem Header="b"></TreeViewItem>
        </TreeView.Items>
    </TreeView>
    <TreeView x:Name="t2" ItemsSource="{Binding Items, ElementName=t1}"></TreeView>
</StackPanel>

我希望t2的节点数与t1相同。但是结果是t1的所有节点都被删除了。 Why

我预期的结果:

enter image description here

实际结果:

enter image description here

2 个答案:

答案 0 :(得分:1)

  

我希望t2的节点数与t1相同。但是结果是t1的所有节点都被删除了。为什么?

因为视觉元素的实例,例如TreeViewItem只能一次出现在视觉树中。一个元素最多只能有一个个可视父元素,在这种情况下,这些元素将从第一个TreeView中删除,然后添加到第二个。

因此,您需要克隆要在两个TreeViewItem中都显示的每个TreeViews元素。

答案 1 :(得分:1)

要回答我自己的问题:

从源代码中找到答案。似乎是设计使然(我仍然不明白为什么要这样设计)。如果给定的项目为TreeViewItem,则它将用作节点容器,而不是创建新的项目。

ItemsControl.cs(第#1323行)

/// <summary>
    /// Return the element used to display the given item
    /// </summary>
    DependencyObject IGeneratorHost.GetContainerForItem(object item)
    {
        DependencyObject container;

        // use the item directly, if possible (bug 870672)
        if (IsItemItsOwnContainerOverride(item))
            container = item as DependencyObject;
        else
            container = GetContainerForItemOverride();

        // the container might have a parent from a previous
        // generation (bug 873118).  If so, clean it up before using it again.
        //
        // Note: This assumes the container is about to be added to a new parent,
        // according to the ItemsControl/Generator/Container pattern.
        // If someone calls the generator and doesn't add the container to
        // a visual parent, unexpected things might happen.
        Visual visual = container as Visual;
        if (visual != null)
        {
            Visual parent = VisualTreeHelper.GetParent(visual) as Visual;
            if (parent != null)
            {
                Invariant.Assert(parent is FrameworkElement, SR.Get(SRID.ItemsControl_ParentNotFrameworkElement));
                Panel p = parent as Panel;
                if (p != null && (visual is UIElement))
                {
                    p.Children.RemoveNoVerify((UIElement)visual);
                }
                else
                {
                    ((FrameworkElement)parent).TemplateChild = null;
                }
            }
        }

        return container;
    }

还有TreeView(第400行)

public class TreeView : ItemsControl {
    ...
    /// <summary>
    ///     Returns true if the item is or should be its own container.
    /// </summary>
    /// <param name="item">The item to test.</param>
    /// <returns>true if its type matches the container type.</returns>
    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is TreeViewItem;
    }
    ....
}
相关问题