【问题标题】:TreeView ItemSource binding to ViewModel not updating xaml control's ItemsTreeView ItemSsource 绑定到 ViewModel 不更新 xaml 控件项
【发布时间】: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,我想将其用于绑定。 Source DP 只是消费者和 UC 的输入桥。无论如何,DP和VM绑定没有错,只是设计中的一个错误。对不起,谢谢大家。
  • 这不是您设计控件的方式。您希望允许您的控件与不同的视图模型类或数据上下文一起使用。您不会使用“视图模型”在内部备份您的控件。您添加包含此控件的逻辑和属性的代码隐藏文件或类。您必须将 TreeView 直接绑定到 Source 属性(或手动分配)。不要在内部使用“视图模型”。如果您的控件将直接链接到数据源,例如直接从数据库中读取,那么视图模型将是有意义的。但通常控件是被动显示数据而不是管理它

标签: .net wpf user-controls treeview prism


【解决方案1】:

经过一点调试,我发现了问题,完全是我的错,与DP或VM绑定无关。

我有 2 个 ViewTree 控件的使用者。在 ViewTree 中,我订阅了一个事件,当它触发时,两个 ViewTree 元素都会调用处理程序。

在未初始化 TreeSource 的消费者 ViewTree 上引发了异常。

【讨论】:

    猜你喜欢
    • 2012-08-15
    • 1970-01-01
    • 2023-03-09
    • 2010-10-16
    • 1970-01-01
    • 2012-12-10
    • 2017-12-14
    • 1970-01-01
    • 2014-08-06
    相关资源
    最近更新 更多