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

时间:2013-10-22 15:32:25

标签: c# wpf mvvm viewmodel

我的计划由地面级TreeViewcontentPresenters组成。 mainWindow,TreeView和每个contentPresenter都有自己的viewModel。

我想在mainWindowViewModel的{​​{1}}中调用一个函数。

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

但这没有多大意义。因为MWVM不是public MainWindowViewModel ViewModel { get { return DataContext as MainWindowViewModel; } } 的{​​{1}}。

2 个答案:

答案 0 :(得分:11)

  

此中使用的delegate方法和链接的答案可用于任何父子关系和任一方向。这包括从子视图模型到父视图模型,子Window后面的代码后面的Window代码,甚至没有涉及任何UI的纯数据关系。您可以在MSDN上的Delegates (C# Programming Guide)页面上找到有关使用delegate个对象的详细信息。

我今天早些时候刚刚回答了类似的问题。如果您查看Passing parameters between viewmodels帖子,您会看到答案涉及使用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.Command属性转换为父视图模型中的ICommand属性:

TreeViewView

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

当然,这假设有问题的父视图模型的实例被设置为DataContext的{​​{1}}。

答案 1 :(得分:1)

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