我的程序由地面上的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不是TreeViewViewModel
的DataContext
。
本文和链接答案中使用的
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}}}" />
当然,这假设所讨论的父视图模型的实例被设置为MainWindow
的DataContext
。
最简单的方法是将方法作为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();
}
}