将TreeView UserControl的SelectedItem传递给调用Window

时间:2017-01-16 20:50:40

标签: c# wpf xaml user-controls treeview

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

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

我的窗口:

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

使用CodeBehind:

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

我的用户控件

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

使用CodeBehind:

<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;
}

1 个答案:

答案 0 :(得分:1)

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

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

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

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

看起来它不会导致问题,但作为附加说明,您要为UserControl设置两次DataContext。进入UserControl的构造函数后,您将自行引用,然后在对话框中设置DataContext时将其覆盖。在这种情况下,它看起来不会导致问题(除了一些轻微的低效率),但如果你改变了在对话框中设置UserControl的DataContext的方式,它可能会产生意想不到的副作用。 / p>