wpf как связать одно TreeView с другим TreeView - PullRequest
0 голосов
/ 06 сентября 2018

Я пытаюсь связать TreeView t2 с TreeView t1 в xaml, как показано ниже:

<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 голосов
/ 07 сентября 2018

Чтобы ответить на мой вопрос:

Нашел ответ из исходного кода. Кажется, это сделано по собственному усмотрению (я до сих пор не понимаю, почему это так). Если данный элемент равен 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;
    }
    ....
}
0 голосов
/ 06 сентября 2018

Я ожидал, что t2 будет иметь такое же количество узлов, что и t1. Но в результате все узлы t1 удаляются. Почему?

Поскольку экземпляр визуального элемента, такого как, например, TreeViewItem, может отображаться только один раз в визуальном дереве. Элемент может иметь не более одного визуального родителя, и в этом случае элементы удаляются из первого TreeView и добавляются ко второму.

Таким образом, вам нужно клонировать каждый элемент TreeViewItem, который вы хотите отображать в обоих TreeViews.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...