【问题标题】:Use selectedItem of treeview from another ViewModel使用来自另一个 ViewModel 的 treeview 的 selectedItem
【发布时间】:2020-06-23 12:35:58
【问题描述】:

我是 MVVM/WPF 的新手,并尝试使用 MVVM 设计模式。我不知道如何描述我的问题,但假设我有 2 个 ViewModel,如下图所示

RedViewModel 有一个树视图。当用户单击树视图时,它会获取 selectedItem 并发送到 BlueViewModel。基于 RedViewModel 中的 selectedItem,BlueViewModel 在文本框中显示 selectedItem 的数据。

我不知道如何在 2 个 MVVM 之间访问和使用变量。

【问题讨论】:

  • 您可以使用从 RedViewModel 中选择项目时触发的 EventHandler。
  • 你能给我更详细的例子吗:((
  • RedViewModel 有一个树视图。 那不是 MVVM,你正在破坏 MVVM。 ViewModel 应该对 View 一无所知
  • 不,我不是那个意思,让图像我是usimh Josh Smith的FamilyTreeviewModel,当我点击每个人时,它会显示另一个包含个人详细信息(姓名,电子邮件,电话号码,地址...)
  • 窗口不是视图模型...

标签: c# wpf mvvm


【解决方案1】:

选项 1: 红色和蓝色视图可以共享相同的视图模型。然后它们可以简单地绑定到相同的属性。

选项 2:如果您想坚持使用单独的视图模型类,您可以在使用 event aggregator or a messenger 选择项目时从RedViewModelBlueViewModel 发送松散耦合消息。

How do I notify a parent view of a child view event in an MVVM WPF application?

选项 3:在两个视图模型中使用 shared service

【讨论】:

  • 非常感谢 mm8,选项 2 似乎可以解决我的问题。在使用 wpf/mvvm 时,这也是要学习的新东西
  • 我只有 1 个问题。哪个选项最适合我的这种情况。你能推荐我哪个吗?
【解决方案2】:

您不能绑定到标准 WPF TreeViewSelectedItem。但是,您可以使用 Beahvior 类创建可绑定属性

public class perTreeViewHelper : Behavior<TreeView>
{
    public object BoundSelectedItem
    {
        get => GetValue(BoundSelectedItemProperty);
        set => SetValue(BoundSelectedItemProperty, value);
    }

    public static readonly DependencyProperty BoundSelectedItemProperty =
        DependencyProperty.Register("BoundSelectedItem",
            typeof(object),
            typeof(perTreeViewHelper),
            new FrameworkPropertyMetadata(null,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                OnBoundSelectedItemChanged));

    private static void OnBoundSelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        if (args.NewValue is perTreeViewItemViewModelBase item)
        {
            item.IsSelected = true;
        }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
        base.OnDetaching();
    }

    private void OnTreeViewSelectedItemChanged(object obj, RoutedPropertyChangedEventArgs<object> args)
    {
        BoundSelectedItem = args.NewValue;
    }
}

这样,您可以绑定到一个 ViewModel 上的属性,您可以从另一个 ViewModel 引用该属性。显然,这两个 ViewModel 需要以某种方式链接 - 通常是通过将一个作为另一个的属性。

在我的blog post 上详细了解我在 WPF/MVVM 上下文中对 TreeViews 的看法。

【讨论】:

  • 这似乎不是我真正想问的。 Josh Smith 的familytreeview 有自己的selectedItem。我可以使用它,但只能在 FamilyTreeViewModel 范围内使用。如果我想双击treeviewItem,让图像显示另一个视图,我可以显示姓名、电子邮件、电话号码、地址......我该如何实现它
猜你喜欢
  • 2017-09-07
  • 2019-06-01
  • 2011-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多