如何在 WPF/MVVM 中访问子用户控件的 DependencyProperty?
How to access a DependencyProperty of child user control in WPF/MVVM?
我有一个 MainWindow.xaml
,如下所示:
<TabControl TabStripPlacement="Left">
<TabItem Header="Display Tree Data Details" HorizontalAlignment="Left">
<uControls:DisplayDataUserControl />
</TabItem>
<TabItem Header="Configuration" HorizontalAlignment="Left">
------
</TabItem>
<TabItem Header="About" HorizontalAlignment="Left">
------
</TabItem>
<TabItem Header="Sponsors" HorizontalAlignment="Left">
------
</TabItem>
</TabControl>
我的 DisplayDataUserControl
使用另一个名为 treeUserControl
的用户控件。我制作了 treeUserControl,以便我可以在我的 WPF 应用程序中的任何地方重复使用它。
<UserControl x:Class="WpfApplication2.DisplayDataUserControl "
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="thisUC"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<local:treeUserControl />
<Grid>
<!-- display the details of the selected treeviewitem from "treeUserControl" here. -->
</Grid>
</Grid>
</UserControl>
treeUserControl
是一个 UserControl,它通过使用 DependecyPropety (SelectedItem_
) 扩展 TreeView
来显示树数据,定义如下:
<UserControl x:Class="WpfApplication2.treeUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="thisUC"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<local:ExtendedTreeView ItemsSource="{Binding Items}"
SelectedItem_="{Binding MyTreeSelectedItem, Mode=TwoWay}">
.....
</local:ExtendedTreeView>
</Grid>
依赖属性定义:
public class ExtendedTreeView : TreeView
{
public ExtendedTreeView() : base()
{
this.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(___ICH);
}
void ___ICH(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (SelectedItem != null)
{
SetValue(SelectedItem_Property, SelectedItem);
}
}
public object SelectedItem_
{
get { return (object)GetValue(SelectedItem_Property); }
set { SetValue(SelectedItem_Property, value); }
}
public static readonly DependencyProperty SelectedItem_Property = DependencyProperty.Register("SelectedItem_", typeof(object), typeof(ExtendedTreeView), new UIPropertyMetadata(null));
}
我可以在 DisplayDataUserControl
中访问 treeUserControl 的 MyTreeSelectedItem
viewmodel 属性 以便它可以显示有关所选树视图项目的详细信息吗?
您的绑定层次结构看起来不对。
你现在看起来是什么
<TabControl>
<TabItem>
<TreeUserControl>
<ExtendedTreeView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" />
</TreeUserControl>
</TabItem>
...
</TabControl>
你应该拥有的是这样的:
<TabControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<TabItem> <!-- DataContext is SelectedItem -->
<TreeUserControl> <!-- DataContext is SelectedItem -->
<ExtendedTreeView /> <!-- DataContext is SelectedItem -->
</TreeUserControl>
</TabItem>
...
</TabControl>
在第二个示例中,TabItem、TreeUserControl 和 ExtendedTreeView 的 .DataContext
都将是 SelectedItem
(这将是 Items
集合中的一项),因为the DataContext is by default inherited from the parent object.
我知道你在 ExtendedTreeView
中使用了 Items
而我在 TabControl
中使用了它,但是我不知道你的应用程序的正确结构在那里给你任何建议。这应该能让您了解自己做错了什么,以便您可以更正它。
我有一个 MainWindow.xaml
,如下所示:
<TabControl TabStripPlacement="Left">
<TabItem Header="Display Tree Data Details" HorizontalAlignment="Left">
<uControls:DisplayDataUserControl />
</TabItem>
<TabItem Header="Configuration" HorizontalAlignment="Left">
------
</TabItem>
<TabItem Header="About" HorizontalAlignment="Left">
------
</TabItem>
<TabItem Header="Sponsors" HorizontalAlignment="Left">
------
</TabItem>
</TabControl>
我的 DisplayDataUserControl
使用另一个名为 treeUserControl
的用户控件。我制作了 treeUserControl,以便我可以在我的 WPF 应用程序中的任何地方重复使用它。
<UserControl x:Class="WpfApplication2.DisplayDataUserControl "
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="thisUC"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<local:treeUserControl />
<Grid>
<!-- display the details of the selected treeviewitem from "treeUserControl" here. -->
</Grid>
</Grid>
</UserControl>
treeUserControl
是一个 UserControl,它通过使用 DependecyPropety (SelectedItem_
) 扩展 TreeView
来显示树数据,定义如下:
<UserControl x:Class="WpfApplication2.treeUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="thisUC"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<local:ExtendedTreeView ItemsSource="{Binding Items}"
SelectedItem_="{Binding MyTreeSelectedItem, Mode=TwoWay}">
.....
</local:ExtendedTreeView>
</Grid>
依赖属性定义:
public class ExtendedTreeView : TreeView
{
public ExtendedTreeView() : base()
{
this.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(___ICH);
}
void ___ICH(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (SelectedItem != null)
{
SetValue(SelectedItem_Property, SelectedItem);
}
}
public object SelectedItem_
{
get { return (object)GetValue(SelectedItem_Property); }
set { SetValue(SelectedItem_Property, value); }
}
public static readonly DependencyProperty SelectedItem_Property = DependencyProperty.Register("SelectedItem_", typeof(object), typeof(ExtendedTreeView), new UIPropertyMetadata(null));
}
我可以在 DisplayDataUserControl
中访问 treeUserControl 的 MyTreeSelectedItem
viewmodel 属性 以便它可以显示有关所选树视图项目的详细信息吗?
您的绑定层次结构看起来不对。
你现在看起来是什么
<TabControl>
<TabItem>
<TreeUserControl>
<ExtendedTreeView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" />
</TreeUserControl>
</TabItem>
...
</TabControl>
你应该拥有的是这样的:
<TabControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<TabItem> <!-- DataContext is SelectedItem -->
<TreeUserControl> <!-- DataContext is SelectedItem -->
<ExtendedTreeView /> <!-- DataContext is SelectedItem -->
</TreeUserControl>
</TabItem>
...
</TabControl>
在第二个示例中,TabItem、TreeUserControl 和 ExtendedTreeView 的 .DataContext
都将是 SelectedItem
(这将是 Items
集合中的一项),因为the DataContext is by default inherited from the parent object.
我知道你在 ExtendedTreeView
中使用了 Items
而我在 TabControl
中使用了它,但是我不知道你的应用程序的正确结构在那里给你任何建议。这应该能让您了解自己做错了什么,以便您可以更正它。