将 TreeView UserControl 的 SelectedItem 传递给调用 Window

Passing SelectedItem of a TreeView UserControl to the calling Window

我创建了一个对话框 (Window),我在其中使用了带有 TreeView 的 UserControl。现在我需要 dialog/window 中的 TreeView (Getter) 的 SelectedItem。

我已经尝试使用 DependencyProperty,但如果我将断点设置到对话框的 SelectedItem 属性,它不会触发。


我的Window:

<itemViewer:ItemViewerControl DataContext="{Binding ListOfWorldItems}" 
                              SelectedItem="{Binding SelectedWorldItem, Mode=TwoWay}"/>/>

使用代码隐藏:

public WorldItem SelectedWorldItem
{
    get { return selectedWorldItem; }
    set
    {
        selectedWorldItem = value;
        NotifyPropertyChanged("SelectedWorldItem");
    }
}

我的用户控件

<itemViewer:ItemViewerControl DataContext="{Binding ListOfWorldItems}" />

使用代码隐藏:

<UserControl ... >
    <UserControl.Resources>
        ... 
    </UserControl.Resources>

    <Grid>
        <TreeView x:Name="WorldItemsTreeView" 
                  SelectedItemChanged="TreeView_SelectedItemChanged"
                  ItemsSource="{Binding}" />
    </Grid>

</UserControl>




public static readonly DependencyProperty SelectedItemProperty =
    DependencyProperty.Register("SelectedItem", typeof(WorldItem), typeof(ItemViewerControl), new UIPropertyMetadata(null));


public ItemViewerControl()
{
    InitializeComponent();
    DataContext = this;
}

public WorldItem SelectedItem
{
    get { return (WorldItem)GetValue(SelectedItemProperty); }
    set { SetValue(SelectedItemProperty, value); }
}

private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    SelectedItem = (WorldItem)WorldItemsTreeView.SelectedItem;
}

您 运行 遇到的问题是您在 UserControl 上设置 DataContext,然后尝试声明绑定。默认情况下,绑定将从包含绑定的元素的 DataContext 获取其值。在本例中是 ListOfWorldItems,而不是对话框。因此 SelectedItem 属性 在 UserControl 上的绑定实际上失败了(您可以在调试应用程序时在输出 window 中看到这一点)。

解决此问题的一种方法是显式设置绑定源,而不是依赖默认行为。如果您将对话框中的行更改为以下...

<itemViewer:ItemViewerControl DataContext="{Binding ListOfWorldItems}" 
                              SelectedItem="{Binding SelectedWorldItem, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=Window}"/>

它现在应该将您的对话框视为绑定源,并在您的 UserControl 和对话框之间正确建立绑定。请注意,您在 UserControl 和对话框之间建立的任何其他绑定也会显式建立源,否则它们将 运行 变成您在此处遇到的相同问题。

它看起来不像是导致问题的原因,但作为附加说明,您为 UserControl 设置了两次 DataContext。一旦进入 UserControl 的构造函数,您就是 self-referencing,然后在对话框中设置 DataContext 时它会被覆盖。在这种情况下,它看起来不像是导致问题的原因(除了一些小的效率低下),但如果您更改了在对话框中设置 UserControl 的 DataContext 的方式,它可能会出现意外 side-effects。