【发布时间】:2023-03-07 02:52:01
【问题描述】:
我在应用程序中有一个设置窗口,其中有一个按钮用于“保存和关闭”操作。
现在,viewmodel 知道如何保存数据,命令存在并通过 Xaml 中的{Binding ...} 链接。
要关闭窗口,我将元素本身作为命令参数传递。我在实践中并不关心它,但我想知道解决这个问题的“好的 MVVM 方式”是什么。在这种情况下,将 UI 行为分开的理想/教科书方式是什么?
【问题讨论】:
我在应用程序中有一个设置窗口,其中有一个按钮用于“保存和关闭”操作。
现在,viewmodel 知道如何保存数据,命令存在并通过 Xaml 中的{Binding ...} 链接。
要关闭窗口,我将元素本身作为命令参数传递。我在实践中并不关心它,但我想知道解决这个问题的“好的 MVVM 方式”是什么。在这种情况下,将 UI 行为分开的理想/教科书方式是什么?
【问题讨论】:
关闭窗口是视图的责任,因此应该由视图中的某些东西来完成。 保存数据是模型的职责,通过视图模型。 您需要的是视图中将关闭该窗口的内容。 还有一些方法可以告诉它从视图模型中关闭。 视图模型告诉视图发生变化的最明显方式是绑定。
我的方法是从视图模型中绑定一个命令。该命令进行保存,然后设置绑定的 bool 属性。 视图绑定到该属性并自行关闭。 这样视图模型就不需要对窗口的任何引用。 它所做的只是设置它的一个属性。
这里有一些代码可以让您体验一下。
我想一旦你看到它,你可能会明白这一点。
有一个类继承自没有 ui 的控件。
CloseMe 看起来像:
public class CloseMe : Control
{
public bool? Yes
{
get
{
return (bool?)GetValue(YesProperty);
}
set
{
SetValue(YesProperty, value);
}
}
public static readonly DependencyProperty YesProperty =
DependencyProperty.Register("Yes",
typeof(bool?),
typeof(CloseMe),
new PropertyMetadata(null, new PropertyChangedCallback(YesChanged)));
private static void YesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((bool?)e.NewValue != true)
{
return;
}
var me = (CloseMe)d;
Window parent = Window.GetWindow(me) as Window;
parent.Close();
}
}
在我的窗口中:
<local:CloseMe Yes="{Binding CloseWindow, Mode=TwoWay}"/>
CloseWindow 是我在该视图模型中提到的 bool 属性。 将其设置为 true,CloseMe 控件 YesProperty 将更改为 true。回调触发并查找其父窗口的可视化树。然后关闭该窗口并...完成。
【讨论】: