【问题标题】:Communication between 6 ViewModels and a Messenger == AntiPattern?6 个 ViewModel 和一个 Messenger == AntiPattern 之间的通信?
【发布时间】:2010-10-13 21:27:08
【问题描述】:

在 2 个 ViewModel 之间进行通信的常用方法是:MVVM- View Model-View Model Communications

中介者模式或信使类。但是一个 Window 中有 6 个 ViewModel 呢?

  1. NewSchoolclassUserControl
  2. NewPupilUserControl
  3. SchoolclassListUserControl
  4. PupilListUserControl
  5. PupilsDetailUserControl
  6. 管理按钮栏用户控件 (有按钮执行命令)

所有这些都在一个窗口中。 “你”现在真的告诉我我必须为这 6 个视图及其 Viewodels 设置一个 Messenger 吗?那太可怕了……

6 个用户控件在一个窗口中,即使是大型企业应用程序在一个窗口中也没有更多用户控件,那么在这种情况下,什么是公认的/最佳实践?

我会对有大型 mvvm 应用程序经验的人的意见感兴趣:)

其中一些 UserControl+ViewModel 我想在我的应用程序的其他地方重用。所以把所有的 UserControl 都放在一个 UserControl 中并不是我真正想要的。

更新:为了盲人 ;-)

private DateTime _selectedDate;
        public DateTime SelectedDate
        {
            get { return _selectedDate; }
            set
            {
                if (_selectedDate == value)
                    return;

                _selectedDate = value;
                this.RaisePropertyChanged("SelectedDate");


                ObservableCollection<Period> periods = _lessonplannerRepo.GetLessonDayByDate(SelectedDate);

                _periodListViewModel = new ObservableCollection<PeriodViewModel>();

                foreach (Period period in periods)
                {
                    PeriodViewModel periodViewModel = new PeriodViewModel(period);

                    foreach (DocumentListViewModel documentListViewModel in periodViewModel.DocumentViewModelList)
                    {
                        documentListViewModel.DeleteDocumentDelegate += new Action<List<Document>>(OnDeleteDocument);
                        documentListViewModel.AddDocumentDelegate += new Action(OnAddDocument);
                        documentListViewModel.OpenDocumentDelegate += new Action<Document>(OnOpenDocument);
                    }

                    _periodListViewModel.Add(periodViewModel);                    

                } 
            }
        }

@blindmeise

这个 ViewModel 实际上是一个 DataGrid 的数据模板。期间是行。每行都有一个名为 Documents 的列。我有一个 PeriodListViewModel 1 : N DocumentListViewModel。

DocumentListViewModel 是使用包含 ListBox 的 UserControl 和下面的一些按钮添加/删除/保存/打开等的数据模板化...

DocumentListViewModel 具有在“LessonController”中执行的命令和操作委托,因此对 Document 的每个操作(如添加、删除等)都可以在 LessonController 中声明的 SelectedPeriodViewModel 上完成。

当用户更改日期选择器中的日期时,上面的代码只是从数据库中加载新数据。

您是否需要更多代码,或者您对我的方法有何看法?我渴望学习,我为每一个批评者感到高兴!

【问题讨论】:

  • 在一个窗口中有 6 或 60 个“用户”控件并没有错。只有可用和不可用的 UI。

标签: mvvm communication viewmodel mediator


【解决方案1】:

如果您有 6 或 1000 个松散耦合的 viewmodel 应该相互通信,那么您应该使用 messenger/mediator。它根本与用户控件无关。

如果您的视图模型相互引用,那么您就不需要信使,但它不再松散耦合:)

编辑: 真的很难说你能做得更好,因为我不知道你想用你的应用程序和你的应用程序设计实现什么:) 一般来说,这取决于你如何为你的视图模型指定任务以及你想如何耦合这些视图模型。也许你应该从 www 上查看一些示例项目 :) 有很多 mvvm 实现,它们变化很大,但可以更好地理解 mvvm 模式(模式!!不是规则!!;))

想象你有一个视图模型,它什么都不做,然后选择一个日期。这将是一个简单的松耦合虚拟机。您现在所能做的就是在选择新日期时,通过信使发送消息。

public DateTime SelectedDate
{
    get { return _selectedDate; }
    set
    {
         if (_selectedDate == value)
             return;

          _selectedDate = value;
          this.RaisePropertyChanged("SelectedDate");

          this.messenger.Notify("SelectedDateChanged", this.SelectedDate)
     }
 }

现在所有其他松散耦合的视图模型都可以注册到调解器和“SelectedDateChanged”消息,并在日期更改时执行想要执行的操作。 这可能不适合您的设计,但应该让您对信使模式有所了解。

【讨论】:

  • 好吧,我的视图模型是指其他视图模型,因为如果您在 schoolclassListViewModel 中选择一个学校班级,则 PupilListViewModel 中的学生列表必须更改。我听说聚合 ViewModel 是不行的……
  • 如果您有从视图模型到视图模型的引用,您不需要中介,您可以使用事件,例如。也许你可以发布一些代码(vm + view)。你用什么 mvvm 方法?先查看还是先查看模型?
  • 我使用 atm View first 方法,但由于 MEFedMVVM 和服务等原因,我可能会先切换到 ViewModel... 返回主题:
  • 回到主题。在一个窗口中有多少个用户控件并不重要。真正的问题是您的视图模型如何相互关联/引用以及视图模型应如何通信。调解器/信使模式只是实现视图模型之间松散耦合设计的一种机会。也许您应该稍微说明一下您的问题?
  • 抱歉回到主题很愚蠢...我发送了帖子但实际上还没有完成但我无法再编辑它...现在我已经更新了我的初始化帖子! :) 感谢您阅读老兄。
猜你喜欢
  • 2015-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
相关资源
最近更新 更多