WPF中MVVM下的父子视图通信
Parent and Child View communication under MVVM on WPF
我已经为这个问题苦苦挣扎了一段时间。我正在构建我的第一个 WPF MVVM 应用程序。在此应用程序中,我有一个 AppView(及其相应的视图模型)。子视图包含在选项卡中并由单独的视图(用户控件)表示,并且每个视图都有一个视图模型。到目前为止,一切都很好。
在一个视图中,有一个客户列表和一个删除按钮。我在视图模型上也有一个 correspondig 命令来实际删除记录,这个工作正常。现在我想要删除按钮创建一个带有两个按钮的新视图,一个用于确认,另一个用于取消,然后如果用户单击 "Confirm" 按钮,则执行删除。
这里的问题是每个视图及其对应的视图模型都是相互隔离的(据我所知),所以我无法访问第二个视图视图模型以查看是否单击了确认按钮。
目前我找到的唯一可行的解决方案是在一个视图上添加一个事件并将另一个视图订阅该事件。但这项技术对于这样一项微不足道的任务来说是相当复杂的。还有其他选择吗?两个视图不能共享相同的数据上下文或视图模型吗?
谢谢!
var dialog = new DialogViewModel();// could be a DialogService if you wish
在此 DialogViewModel 或 DialogService 中,您可以再次选择实际操作方式。
dialog.Result 在这种情况下 return 您的确认要么是真要么是假
var settings = new Dictionary<string, object>();
settings["Owner"] = this;
settings["WindowStartupLocation"] = WindowStartupLocation.CenterParent;
windowManager.ShowDialog(dialog, null, settings);
if(dialog.Result == true)
do the delete on the parent viewmodel.
或者您可以使用 IEventAggregator 和消息包来完成这一切。我个人将第一个用于很多事情。有时根据情况组合。
大多数人会喜欢 SoC 的 IDialogService 方法,并使用它进行 DI 以将其带入使用它的视图模型中。然后每个视图模型将负责自己的对话框。从那里您可以调用 ShowDialog,因为它是 WindowManager 的一部分,您可以单击是或否,或者您为对话视图设置的任何内容。给猫剥皮的方法有很多,但最后你想要 KISS 方法和一些不会破坏你试图坚持的模式的东西。不管怎样,你都可以将它添加到 viewmodelbase base class for您要继承的所有视图模型都可以全局访问。无论如何,所有功能都取决于您希望您的应用程序如何运行。
--更新--
public class YourViewModel(IWindowManager winMan)
{
private readonly IWindowManager _winMan;
public YourViewModel()
{
_winMan = winMan;
}
public void DeleteCustomer()
{
var dialog= new DialogViewModel(); // not best way but...
var settings = new Dictionary<string, object>();
settings["Owner"] = this; //<< Parent
settings["StartupLocation"] = WindowStartupLocation.CenterParent;
_winMan.ShowDialog(dialog, null, settings);
if(dialog.Result)
//do delete
else
//do nothing
}
}
我已经为这个问题苦苦挣扎了一段时间。我正在构建我的第一个 WPF MVVM 应用程序。在此应用程序中,我有一个 AppView(及其相应的视图模型)。子视图包含在选项卡中并由单独的视图(用户控件)表示,并且每个视图都有一个视图模型。到目前为止,一切都很好。
在一个视图中,有一个客户列表和一个删除按钮。我在视图模型上也有一个 correspondig 命令来实际删除记录,这个工作正常。现在我想要删除按钮创建一个带有两个按钮的新视图,一个用于确认,另一个用于取消,然后如果用户单击 "Confirm" 按钮,则执行删除。
这里的问题是每个视图及其对应的视图模型都是相互隔离的(据我所知),所以我无法访问第二个视图视图模型以查看是否单击了确认按钮。
目前我找到的唯一可行的解决方案是在一个视图上添加一个事件并将另一个视图订阅该事件。但这项技术对于这样一项微不足道的任务来说是相当复杂的。还有其他选择吗?两个视图不能共享相同的数据上下文或视图模型吗?
谢谢!
var dialog = new DialogViewModel();// could be a DialogService if you wish
在此 DialogViewModel 或 DialogService 中,您可以再次选择实际操作方式。
dialog.Result 在这种情况下 return 您的确认要么是真要么是假
var settings = new Dictionary<string, object>();
settings["Owner"] = this;
settings["WindowStartupLocation"] = WindowStartupLocation.CenterParent;
windowManager.ShowDialog(dialog, null, settings);
if(dialog.Result == true)
do the delete on the parent viewmodel.
或者您可以使用 IEventAggregator 和消息包来完成这一切。我个人将第一个用于很多事情。有时根据情况组合。
大多数人会喜欢 SoC 的 IDialogService 方法,并使用它进行 DI 以将其带入使用它的视图模型中。然后每个视图模型将负责自己的对话框。从那里您可以调用 ShowDialog,因为它是 WindowManager 的一部分,您可以单击是或否,或者您为对话视图设置的任何内容。给猫剥皮的方法有很多,但最后你想要 KISS 方法和一些不会破坏你试图坚持的模式的东西。不管怎样,你都可以将它添加到 viewmodelbase base class for您要继承的所有视图模型都可以全局访问。无论如何,所有功能都取决于您希望您的应用程序如何运行。
--更新--
public class YourViewModel(IWindowManager winMan)
{
private readonly IWindowManager _winMan;
public YourViewModel()
{
_winMan = winMan;
}
public void DeleteCustomer()
{
var dialog= new DialogViewModel(); // not best way but...
var settings = new Dictionary<string, object>();
settings["Owner"] = this; //<< Parent
settings["StartupLocation"] = WindowStartupLocation.CenterParent;
_winMan.ShowDialog(dialog, null, settings);
if(dialog.Result)
//do delete
else
//do nothing
}
}