【发布时间】:2015-01-04 04:00:44
【问题描述】:
我有一个子窗口,并且有一个 ComboBox。我想使用 WPF 和 MVVM 将子窗口的值发送到父窗口。谁能帮我怎么做??
【问题讨论】:
-
您能帮我们说说您尝试过什么吗?
我有一个子窗口,并且有一个 ComboBox。我想使用 WPF 和 MVVM 将子窗口的值发送到父窗口。谁能帮我怎么做??
【问题讨论】:
在这种情况下不要专注于 MVVM,MVVM 不是为将值从子窗口传回父窗口而设计的。
相反,如果您在视图模型中有一些代码或在生成或打开子窗口的视图后面的代码,则该代码应负责检索由子窗口确定的值并将其传播回适当的属性(此时任何绑定都会在 UI 中反映该值 - 这是应该使用 MVVM 的地方)。
您可以做的最好的事情是确保打开子窗口的代码不会直接访问子窗口上的 ComboBox,而是子窗口应将其绑定到一个属性,然后由父代码访问该属性(最好通过接口)。
如需进一步阅读,请查看Creating an MVVM friendly dialog strategy。这应该是您的首选方案,然后父代码简单地使用 Dialog Service 来显示子窗口,而 Dialog Service 负责聚合子窗口结果并将其返回给父窗口中的调用代码。
【讨论】:
由于您没有提供足够的信息,因此假设子窗口是一个对话框。现在,让我们假设子窗口是一个 Child() 类,其 ViewModel 具有 Child 类中的对象,比如
public ChildViewModel chVM { get; set; }
这个视图模型具有以下属性:
public string ComboBoxSelectedValue { get; set; }
让具有组合框的对话框的 xaml 如下所示:-
<ComboBox Name="cbTest" SelectedItem="{Binding ComboBoxSelectedValue}">
<ComboBoxItem>A</ComboBoxItem>
<ComboBoxItem>B</ComboBoxItem>
<ComboBoxItem>C</ComboBoxItem>
</ComboBox>
现在,每次在 combobnox 中选择一个值时,其视图模型中的属性,即 ComboBoxSelectedValue 都会被选择的值填充。
您必须在父页面上处理对话框的关闭事件。让我们转到作为父页面的类 Parent():
public partial class Parent : Page
{
private Child ch;
public Parent()
{
InitializeComponent();
ch= new Child();
ch.Closed += ChildClosed;
}
public void ChildClosed(object sender, System.EventArgs e)
{
//even after closing of child window
var selectedValue = ch.chVM.ComboBoxSelectedValue;
}
public void OpenChild(object sender, System.EventArgs e)
{
//Button event to open the child window
ch.Show();
}
}
如果这是您需要的,请回复。否则,请随时要求其他解决方案。这也可以在没有 mvvm 的情况下完成,但是由于您要求使用 MVVM,所以这就是解决方案。
【讨论】:
我发现允许视图模型相互通信的最佳解决方案是通过消息传递框架,我的首选是 nuget 上可用的 MVVM light。
您的子视图模型通过父订阅的框架发送消息。与事件处理程序没有什么不同。
孩子...
Messenger.Default.Send<MyMessageClass>(message);
这可以在组合框中选择项绑定设置器,或命令操作方法的一部分。
家长...
Messenger.Default.Register<MyMessageClass>(this, OnMessage);
MyMessageClass 必须扩展 BaseMessage 并且应该包含您要共享的数据的属性。父级中的 OnMessage 方法应接受此类作为参数,并使用这些值在父级中执行您需要的任何操作。
是更好的 MVVM,因为它将逻辑排除在代码后面或视图之外,但也不会产生强耦合。如果一个视图模型发送了一条其他视图模型没有收到的消息,则什么也不会发生 - 您还可以使用消息对象而不是检查视图模型来共享数据。
msdn here上的教程。
【讨论】: