【发布时间】:2021-11-22 17:55:40
【问题描述】:
我正在创建一个包装 TreeView 元素的 UserControl(我们称之为 ViewTree)。在 ViewTree.xaml.cs 我有一个 Source 依赖属性:
public static readonly DependencyProperty SourceProperty
= DependencyProperty.Register (
"Source",
typeof (ObservableCollection<TreeItem>),
typeof (ViewTree),
new FrameworkPropertyMetadata (new ObservableCollection<TreeItem>(), OnSourceChanged)
);
public ObservableCollection<TreeItem> Source
{
get { return (ObservableCollection<TreeItem>)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
...这样 UserControl 的使用者可以进行输入绑定:
<features:ViewTree Source="{Binding Path=...}">
然而,在 ViewTree UserControl 中,我并不想直接绑定到这个 DependencyProperty。相反,我想绑定到 ViewModel 中的另一个属性(使用 Prism),所以我在 ViewTree.xaml.cs 中执行了此操作:
private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var nextTreeSource = e.NewValue as ObservableCollection<TreeItem>;
if (nextTreeSource == null)
{
return;
}
var viewTree = d as ViewTree;
viewTree.UpdateTreeSource(nextTreeSource);
}
public void UpdateTreeSource(ObservableCollection<TreeItem> treeSource)
{
var vm = trvMenu.DataContext as ViewTreeViewModel;
vm.TreeSource = treeSource;
}
在我的 ViewTree.xaml 中,我有以下内容,并且树节点正常显示:
<TreeView Name="trvMenu" ItemsSource="{Binding Path=TreeSource}">
但是,当我尝试访问 ViewTree.xaml.cs 中的 trvMenu.Items 时,它显示为空。我在viewTree.UpdateTreeSource(nextTreeSource); 后面放了一个断点,可以验证viewTree.trvMenu.Items 里面有孩子。
如果我直接绑定到 DependencyProperty,它可以正常工作,但我仍然更喜欢 ViewModel 绑定。
如果有人能指出我做错了什么,或者这只是 WPF 的工作方式,我将不胜感激?
提前致谢。
【问题讨论】:
-
"with Prism"的意思是你依赖Prism来为你创建用户控件的视图模型?
-
是的,我的 xaml 中有
prism:ViewModelLocator.AutoWireViewModel="True",并在初始化期间使用 ViewModel 类注册 UserControl 的映射。 -
目前还不清楚 UpdateTreeSource 应该做什么。它不会更改 Source 属性的绑定。相反,它会更改 DataContext 中的一个属性。这看起来很奇怪。
-
UpdateTreeSource故意更改上下文 ViewTree 用户控件的 VM,我想将其用于绑定。SourceDP 只是消费者和 UC 的输入桥。无论如何,DP和VM绑定没有错,只是设计中的一个错误。对不起,谢谢大家。 -
这不是您设计控件的方式。您希望允许您的控件与不同的视图模型类或数据上下文一起使用。您不会使用“视图模型”在内部备份您的控件。您添加包含此控件的逻辑和属性的代码隐藏文件或类。您必须将 TreeView 直接绑定到 Source 属性(或手动分配)。不要在内部使用“视图模型”。如果您的控件将直接链接到数据源,例如直接从数据库中读取,那么视图模型将是有意义的。但通常控件是被动显示数据而不是管理它
标签: .net wpf user-controls treeview prism