wpf 如何从其他视图模型调用主视图模型中的函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19522202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call functions in a main view model from other view models?
提问by Eric after dark
My program is composed of a TreeViewand two contentPresentersat ground level. The mainWindow, TreeView, and each contentPresenterall have their own viewModels.
我的程序由一个TreeView和两个contentPresenters在地面上组成。mainWindow、TreeView和 每个contentPresenter都有自己的视图模型。
I would like to call a function in the mainWindowViewModelfrom the TreeViewViewModel.
我想mainWindowViewModel从TreeViewViewModel.
I need to do this because the mainWindowViewModelcontrols what is displayed in the contentPresenters, and I would like to manually update the display.
我需要这样做是因为mainWindowViewModel控制了 中显示的内容contentPresenters,我想手动更新显示。
I'm guessing I would do something like this...
我猜我会做这样的事情......
TreeViewViewModel:
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
}
}
I have tried to get access to the MainWindowVMfrom the TreeViewViewModelby using:
我曾试图让访问MainWindowVM从TreeViewViewModel使用:
public MainWindowViewModel ViewModel { get { return DataContext as MainWindowViewModel; } }
But it doesn't make much sense. because the MWVM is not the DataContextof the TreeViewViewModel.
但这没有多大意义。因为MWVM不是DataContext的TreeViewViewModel。
回答by Sheridan
The
delegatemethod used in this and the linked answer can be used in any parent-child relationship and in either direction. That includes from a child view model to a parent view model, aWindowcode behind to the code behind of a childWindow, or even pure data relationships without any UI involved. You can find out more about usingdelegateobjects from the Delegates (C# Programming Guide)page on MSDN.
delegate此处使用的方法和链接的答案可用于任何父子关系和任一方向。这包括从子视图模型到父视图模型、子视图Window背后的代码Window,甚至不涉及任何 UI 的纯数据关系。您可以delegate从MSDN 上的委托(C# 编程指南)页面找到有关使用对象的更多信息。
I just answered a similar question to this earlier today. If you take a look at the Passing parameters between viewmodelspost, you'll see that the answer involves using delegateobjects. You can simply replace these delegates (from the answer) with your method(s) and it will work in the same way.
我今天早些时候刚刚回答了一个类似的问题。如果您查看在viewmodels帖子之间传递参数,您会发现答案涉及使用delegate对象。您可以简单地delegate用您的方法替换这些s(来自答案),它会以相同的方式工作。
Please let me know if you have any questions.
请让我知道,如果你有任何问题。
UPDATE >>>
更新 >>>
Yes, sorry I completely forgot you wanted to call methods instead... I've been working on too many posts tonight. So still using the example from the other post, just call your method in the ParameterViewModel_OnParameterChangehandler:
是的,抱歉,我完全忘记了您想改为调用方法...今晚我已经写了太多帖子。所以仍然使用其他帖子中的示例,只需在ParameterViewModel_OnParameterChange处理程序中调用您的方法:
public void ParameterViewModel_OnParameterChange(string parameter)
{
// Call your method here
}
Think of the delegateas being your path back to the parent view model... it's like raising an event called ReadyForYouToCallMethodNow.In fact, you don't even need to have an input parameter. You could define your delegatelike this:
将其delegate视为返回父视图模型的路径...就像引发一个名为的事件ReadyForYouToCallMethodNow.实际上,您甚至不需要输入参数。你可以这样定义你的delegate:
public delegate void ReadyForUpdate();
public ReadyForUpdate OnReadyForUpdate { get; set; }
Then in the parent view model (after attaching the handler like in the other example):
然后在父视图模型中(在像另一个示例中那样附加处理程序之后):
public void ChildViewModel_OnReadyForUpdate()
{
// Call your method here
UpdateDisplay();
}
As you have multiple child view models, you could define the delegatein another class that they both have access to. Let me know if you have any more questions.
由于您有多个子视图模型,您可以delegate在它们都可以访问的另一个类中定义。如果您还有其他问题,请告诉我。
UPDATE 2 >>>
更新 2 >>>
After reading your last comment again, I've just thought of a much simpler method that mightachieve what you want... at least, if I understand you correctly. It is possible for you to Binddirectly from your child views to your parent view model. For instance, this would allow you to Binda Button.Commandproperty in a child view to an ICommandproperty in your parent view model:
再次阅读您的最后一条评论后,我刚刚想到了一种更简单的方法,可以实现您想要的……至少,如果我理解正确的话。您可以Bind直接从您的子视图到您的父视图模型。例如,这将允许你Bind一个Button.Command在子视图的财产ICommand在你的父视图模型属性:
In TreeViewView:
在TreeViewView:
<Button Content="Click Me" Command="{Binding DataContext.ParentCommand,
RelativeSource={RelativeSource AncestorType={x:Type MainWindow}}}" />
This of course assumes that an instance of the parent view model in question is set as the DataContextof the MainWindow.
当然,这假定所讨论的父视图模型的一个实例被设置为DataContext的MainWindow。
回答by asdf
The easiest way is to pass a method as Actionto the constructor of the child view model.
最简单的方法是将方法传递给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();
}
}

