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

本文关键字:模型 主视图 函数 调用 其他 视图 | 更新日期: 2023-09-27 18:36:29

我的程序由地面上的TreeView和两个contentPresenters组成。主窗口、TreeView 和每个contentPresenter都有自己的视图模型。

我想从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

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

本文和链接答案中使用的delegate方法可用于任何父子关系和任一方向。这包括从子视图模型到父视图模型,从Window代码到子Window的代码隐藏,甚至是不涉及任何UI的纯数据关系。您可以从 MSDN 上的委托(C# 编程指南)页找到有关使用delegate对象的详细信息。

我今天早些时候刚刚回答了一个类似的问题。如果你看一下在视图模型之间传递参数的文章,你会发现答案涉及使用delegate对象。您可以简单地将这些delegate(来自答案)替换为您的方法,它将以相同的方式工作。

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


更新>>>

是的,对不起,我完全忘记了你想调用方法...今晚我写了太多的帖子。因此,仍然使用另一篇文章中的示例,只需在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到父视图模型。例如,这将允许您将子视图中的Button.Command属性Bind父视图模型中的ICommand属性:

TreeViewView

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

当然,这假设所讨论的父视图模型的实例被设置为MainWindowDataContext

最简单的方法是将方法作为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();
    }
}