【问题标题】:How to establish communication/pass data between two ViewModels如何在两个 ViewModel 之间建立通信/传递数据
【发布时间】:2014-08-06 11:17:49
【问题描述】:

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

我目前正在开发的应用程序如下所示: http://screenshooter.net/100101493/smrkpog

这是一个基于 MVVM Light Toolkit 的 WPF MVVM 应用程序。带有网格的区域是ListBox + Canvas。这些项目(我们称它们为“Neumes”)再次由ListBox + Canvas 组成,并且由用户动态创建。每个 Neume 都由呈现为红色形状的“元素”组成。

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

  1. 完全跳过新的 ViewModel 并将 MainViewModel 设置为新窗口的DataContext
  2. 在新的 ViewModel 中创建一个“MainViewModel”字段,并在打开新窗口时将其传递给那里,
  3. 使用 MVVM Light Toolkit 提供的 Messaging/Mediator 模式。

我正在寻找一种既简单又整洁的解决方案。我很乐意使用选项 3。但就 WPF 而言,我是一个相对新手,不知道如何真正开始。另外,我担心当主 ListBox 上的双击事件被触发时打开新窗口这一事实可能存在问题,因为我找不到将命令绑定到 ListBoxItem 的方法。它的 Style 和 DataTemplate(事件触发器/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.有什么问题吗?可能的内存泄漏?

【问题讨论】:

    标签: c# wpf xaml mvvm mvvm-light


    【解决方案1】:

    我个人会选择选项 3。

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

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

    MVVM Light 是一个很好的框架。

    发送:

    GalaSoft.MvvmLight.Messaging.Messenger.Send<LoginSuccessMessage>(new LoginSuccessMessage() { UserName = user });
    

    接收,在我的目标视图模型构造函数中:

    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);
        }
    

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

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

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

    【讨论】:

    • 这就是我所说的跟踪狂:)
    • 跟踪者也可以很友好 ;)
    • 这还能用吗?我在实施时遇到了困难
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 2018-04-18
    • 2015-09-18
    • 2022-07-29
    相关资源
    最近更新 更多