将 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。
我创建了一个对话框 (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。