如何从其他视图模型调用主视图模型中的函数?

Posted

技术标签:

【中文标题】如何从其他视图模型调用主视图模型中的函数?【英文标题】:How to call functions in a main view model from other view models? 【发布时间】:2013-10-31 13:53:58 【问题描述】:

我的程序由地面层的TreeView 和两个contentPresenters 组成。主窗口TreeView 和每个contentPresenter 都有自己的viewModel。

我想从TreeViewViewModel调用mainWindowViewModel中的一个函数。

我需要这样做,因为mainWindowViewModel 控制contentPresenters 中显示的内容,我想手动更新显示。

我猜我会做这样的事情......

TreeViewViewModel:

public class TreeViewViewModel

     //Do I need to declare the MainWindowVM?

     public TreeViewViewModel()  ... 

     private void function()
     
          //Command that affects display

          //Manually call function in MainWindowVM to refresh View
     

我已尝试使用以下方法从TreeViewViewModel 访问MainWindowVM

public MainWindowViewModel ViewModel  get  return DataContext as MainWindowViewModel;  

但这没有多大意义。因为 MWVM 不是 TreeViewViewModelDataContext

【问题讨论】:

【参考方案1】:

这里使用的delegate 方法和链接的答案可用于任何父子关系和任一方向。这包括从子视图模型到父视图模型、Window 代码后面到子代码后面 Window,甚至是不涉及任何 UI 的纯数据关系。您可以从 MSDN 上的 Delegates (C# Programming Guide) 页面了解有关使用 delegate 对象的更多信息。

我今天早些时候刚刚回答了一个与此类似的问题。如果您查看Passing parameters between viewmodels 帖子,您会发现答案涉及使用delegate 对象。您可以简单地用您的方法替换这些delegates(来自答案),它会以相同的方式工作。

如果您有任何问题,请告诉我。


更新>>>

是的,对不起,我完全忘记了你想调用方法......我今晚写了太多帖子。所以仍然使用另一篇文章中的示例,只需在 ParameterViewModel_OnParameterChange 处理程序中调用您的方法即可:

public void ParameterViewModel_OnParameterChange(string parameter)

    // Call your method here

delegate 视为返回父视图模型的路径...就像引发一个名为ReadyForYouToCallMethodNow. 的事件实际上,您甚至不需要输入参数。你可以像这样定义你的delegate

public delegate void ReadyForUpdate();

public ReadyForUpdate OnReadyForUpdate  get; set; 

然后在父视图模型中(在附加处理程序之后,就像在另一个示例中一样):

public void ChildViewModel_OnReadyForUpdate()

    // Call your method here
    UpdateDisplay();

由于您有多个子视图模型,您可以在它们都可以访问的另一个类中定义delegate。如果您还有其他问题,请告诉我。


更新 2 >>>

再次阅读您的最后一条评论后,我想到了一个更简单的方法,可能实现您想要的……至少,如果我理解正确的话。您可以直接从子视图到父视图模型 Bind。例如,这将允许您将子视图中的 Bind Button.Command 属性转换为父视图模型中的 ICommand 属性:

TreeViewView:

<Button Content="Click Me" Command="Binding DataContext.ParentCommand, 
RelativeSource=RelativeSource AncestorType=x:Type MainWindow" />

这当然假设有问题的父视图模型的实例被设置为MainWindowDataContext

【讨论】:

关于这个答案的唯一与我正在做的不同的是 mainWindowViewModel 是父 ViewModel,这是我试图调用的。这对解决方案有何改变? 使用另一篇文章中的示例,您将在 MainWindowViewModel 类中拥有一个 ParameterViewModel_OnParameterChange 处理程序方法。唯一的区别是您在该处理程序中的更新已经在您想要的位置(在父视图模型中),因此您不需要将 parameter 传递给另一个子视图模型......实际上您可以使用相同的示例,但只需对 ParameterViewModel_OnParameterChange 处理程序中的值执行您想要的操作,而不是将其传递给其他视图模型。 这似乎是关于将值传递给其他 ViewModel,并更改参数值。我只想从另一个 ViewModel 中的 Command/Function 调用 mainWindowViewModel 中的函数。我调用的 MWVM 中的函数只是根据所选内容更改 contentPresenter 中显示的内容。【参考方案2】:

最简单的方法是将方法作为Action 传递给子视图模型的构造函数。

public class ParentViewModel

    ChildViewModel childViewModel;

    public ParentViewModel()
    
        childViewModel = new ChildViewModel(ActionMethod);
    

    private void ActionMethod()
    
        Console.WriteLine("Parent method executed");
    


public class ChildViewModel

    private readonly Action parentAction;

    public ChildViewModel(Action parentAction)
    
         this.parentAction = parentAction;

         CallParentAction();
    

    public void CallParentAction()
    
        parentAction.Invoke();
    

【讨论】:

以上是关于如何从其他视图模型调用主视图模型中的函数?的主要内容,如果未能解决你的问题,请参考以下文章

从视图模型 (WPF) 调用视图中的动画

杜兰达尔/淘汰赛。更新其他视图/视图模型

视图模型应该对视图控制器中的事件做出反应吗?

如何通过主干中的 ajax 调用使用模型渲染多个视图

如何将数据从父模型类传递到 SwiftUI 中的子视图

在 MVC4 中的单个视图中访问多个模型中的项目