C# 如何在两个ViewModel之间建立通信/传递数据

C# 如何在两个ViewModel之间建立通信/传递数据,c#,wpf,xaml,mvvm,mvvm-light,C#,Wpf,Xaml,Mvvm,Mvvm Light,我知道这个问题已经被问过很多次了,我已经读过很多关于它的答案。然而,他们都没有满足我的要求,因此我需要一些建议 我目前正在开发的应用程序如下所示: 它是一个基于MVVM Light Toolkit的WPF MVVM应用程序。带有网格的区域是一个列表框+画布。这些项目(我们称之为“Neumes”)又由一个列表框+画布组成,每个项目都是由用户动态创建的。每个Neume都由渲染为红色形状的“元素”组成 当用户双击Neume时,将打开一个新窗口。它应该能够编辑(平移、调整大小、旋转)由选定Neume组

我知道这个问题已经被问过很多次了,我已经读过很多关于它的答案。然而,他们都没有满足我的要求,因此我需要一些建议

我目前正在开发的应用程序如下所示:

它是一个基于MVVM Light Toolkit的WPF MVVM应用程序。带有网格的区域是一个
列表框
+
画布
。这些项目(我们称之为“Neumes”)又由一个
列表框
+
画布
组成,每个项目都是由用户动态创建的。每个Neume都由渲染为红色形状的“元素”组成

当用户双击Neume时,将打开一个新窗口。它应该能够编辑(平移、调整大小、旋转)由选定Neume组成的元素我想做的是将存储在MainViewModel中的SelectedNeume(带有元素列表)传递给新创建窗口的ViewModel关于如何实现这一点,我有一些想法

  • 完全跳过新的ViewModel,并将MainViewModel设置为新窗口的
    DataContext
  • 在新的ViewModel中创建“MainViewModel”字段,并在打开新窗口时将其传递给该字段
  • 使用MVVM Light Toolkit提供的消息传递/中介模式
  • 我正在寻找一个既简单又整洁的解决方案。我很乐意使用选项3,但就WPF而言,我是一个相对的新手,不知道如何真正开始。另外,我担心当主ListBox上的双击事件被触发时,新窗口可能会打开,因为我找不到将命令绑定到ListBoxItem的方法,无论是样式还是数据模板(event trigger/EventToCommand解决方案对我不起作用)

    这是一个事件:

        private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var item = ((FrameworkElement)e.OriginalSource).DataContext as Neume;
            if (item != null)
            {
                var view2 = new EditWindow();
                view2.Owner = this;
                view2.SetDataContext();
                view2.ShowDialog();
            }
        }  
    
    SetDataContext()
    方法当前负责根据1绑定DataContext。选项:

    public void SetDataContext()
        {
            if(this.Owner != null)
                DataContext = this.Owner.DataContext;
        }
    

    我的问题是:你会推荐哪种选择?这两个1都有问题吗。还是2。?可能的内存泄漏?

    就我个人而言,我会选择选项3

    消息传递机制使您的viewmodels彼此分离,一旦您完成了一个示例,您就会发现它非常简单

    就我个人而言,我喜欢为我想要发送的每种消息类型添加一个带有静态方法的MessageBroker类,这有助于我集中更改—但本质上,您有一个发送和接收。你可以发送你想要的,如果有人想要接收,他们可以

    MVVMLight是一个很好的框架

    发送:

    在本例中,我将用户ID作为message类的属性发送:

    public class LoginSuccessMessage : MessageBase
    {
    
        private string _UserName;
    
        public string UserName
        {
            get
            {
                return this._UserName;
            }
    
            set
            {
                this._UserName = value;
            }
        }
    }
    

    将该属性替换为您想要的集合或复杂对象。

    这就是我所说的跟踪者:)跟踪者也可以是友好的;)这个还能用吗?我执行起来有困难
    this.MessengerInstance.Register<LoginSuccessMessage>(this, this.OnLoginSuccessMessage);
    
        private async void OnLoginSuccessMessage(LoginSuccessMessage message)
        {
            this.CurrentUserName = message.UserName;
            this.MoveToState(ApplicationViewModelState.Active);
    
            await Task.Delay(5000);
            this.MoveToState(ApplicationViewModelState.Idle);
        }
    
    public class LoginSuccessMessage : MessageBase
    {
    
        private string _UserName;
    
        public string UserName
        {
            get
            {
                return this._UserName;
            }
    
            set
            {
                this._UserName = value;
            }
        }
    }