10

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

我想在mainWindowViewModelfrom中调用一个函数TreeViewViewModel

我需要这样做,因为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
     }
}

我试图MainWindowVM通过TreeViewViewModel使用以下方式访问:

public MainWindowViewModel ViewModel { get { return DataContext as MainWindowViewModel; } }

但这没有多大意义。因为MWVM不是DataContext.TreeViewViewModel

4

2 回答 2

11

此处使用的delegate方法和链接的答案可用于任何父子关系和任一方向。这包括从子视图模型到父视图模型、Window代码后面到子代码后面的代码Window,甚至是不涉及任何 UI 的纯数据关系。您可以从 MSDN 上的Delegates(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直接从子视图到父视图模型。例如,这将允许您将子视图中的Bind属性转换为父视图模型中的属性:Button.CommandICommand

TreeViewView

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

这当然假设所讨论的父视图模型的实例被设置DataContextMainWindow.

于 2013-10-22T15:41:31.260 回答
3

最简单的方法是将方法传递给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();
    }
}
于 2018-06-07T08:01:49.603 回答