【问题标题】:Using view method inside ViewModel (MVVM)在 ViewModel (MVVM) 中使用视图方法
【发布时间】:2014-08-18 21:45:21
【问题描述】:

假设我正在使用 FlowDocumentPageViewer,并且我想使用 find 方法。 如何在遵循 MVVM 规则的同时使用它?我做了一些搜索,似乎解决方案是混合的。

有人建议你把View聚合到ViewModel,然后用它来调用需要的方法:

例如:

private MainWindow mw; 

public MainWindowViewModel(MainWindow mw)
{
    this.mw = mw;
}

public void Find()
{
    mw.flowDocument.find();
}

但其他人建议在视图中使用这些方法(代码隐藏)是可以的,因为 ViewModel 不应该调用视图特定的方法。

最后,我听说过使用附加行为来解决这个问题,但我没有深入研究过该方法是否合适。

我真的不知道哪种方法是正确的,或者如果所有这些方法都不正确,如何处理这种情况。如果您能给我一些关于首选哪种方法以及原因的见解,我将不胜感激。

提前感谢您的回答。

【问题讨论】:

  • 好吧,在这里真正帮助您:您打算如何调用该方法?它是绑定在按钮上的吗?然后使用命令。它是基于 PropertyChanged 事件自动执行的吗?然后只需从属性的 ViewModel 中调用它。如果您愿意,请提供有关整体解决方案的更多信息。
  • @Xcalibur37 不,它没有绑定到按钮。这是一种与名为 find 的视图相关联的方法。它是 FlowDocumentPageViewer 的一部分。

标签: c# wpf mvvm view viewmodel


【解决方案1】:

我会用 MVVMLight 消息传递 之类的方法来解决这个问题。 (从您发送消息的 Viewmodel 并在您后面的 View 代码上注册此消息。)

Microsoft 的 Jesse Liberty 有 a great tutorial 介绍如何利用 MVVM Light 中的消息传递。

充当消息类型的类:

public class FlowDocumentFindMessage
{
   public string PageName { get; private set; }
   // or some other properties go here

   FlowDocumentFindMessage(string pageName){
          this.PageName = pageName
   }
}

新的 Find,发送消息

public void Find()
{
    var msg = new FlowDocumentFindMessage("Page");
    Messenger.Default.Send<FlowDocumentFindMessage>( msg );
}

代码隐藏,用于注册新消息

Messenger.Default.Register<GoToPageMessage>( this, ( action ) => ReceiveMessage( action ));

private object ReceiveMessage( FlowDocumentFindMessage action )
{
    //do some stuff
}

【讨论】:

  • 感谢您的帮助!
  • 这是一个很好的 View 和 ViewModel 解耦。不过有几点需要注意:1. 在视图注册之前仔细检查不发送消息,如果您的逻辑依赖于它,您可能会遇到不可预测的状态 2. 在控件 IsLoaded 之前仔细检查您的控件是否支持消息处理程序逻辑,您如果提前调用可能会出现异常如果您在 Loaded 事件或 ViewModel 创建场景中发送消息,请考虑这些,否则您很高兴。
猜你喜欢
  • 2020-08-22
  • 2015-06-27
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 2010-11-27
  • 2010-12-01
相关资源
最近更新 更多