問題
在WPF程序中經常需要用彈出窗口的形式向用戶確認操作,用戶閱讀完相關信息后,點擊上面的OK或者Cancel按鈕來關閉窗口,再進行后續操作。當使用MVVM設計模式時,OK和Cancel會binding到ViewModel中的相關屬性上,因而在用戶點擊了Ok或Cancel之后,我們希望能夠在ViewModel中關閉這個彈窗並返回用戶的選擇結果,但是由於Window類本身所帶的屬性DialogResult不是一個Dependency Proerty,我們也就不能把它Binding到一個ViewModel屬性上,再通過設置該屬性來關閉窗口,那么我們該如何在ViewModel關閉該窗口呢?
解決方案
這里所講的一種解決方案是使用Attached Property。如下所示我們創建了一個靜態類,它包含一個Attached Property:DialogCloser.DialogResult。
public static class DialogCloser
{
public static readonly DependencyProperty DialogResultProperty =
DependencyProperty.RegisterAttached("DialogResult",
typeof(bool?),
typeof(DialogCloser),
new PropertyMetadata(DialogResultChanged));
private static void DialogResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var window = d as Window;
if (window != null)
{
window.DialogResult = e.NewValue as bool?;
}
}
public static void SetDialogResult(Window target, bool? value)
{
target.SetValue(DialogResultProperty, value);
}
}
在使用時,只需要把這個屬性Attach到相關窗口上,並Binding到后台ViewModel的屬性上即可。下面是一個例子,完整代碼請參見 https://github.com/DerekLoveCC/Writings/tree/master/Article/WPF_MVVM_Close_Window/code/CloseWindow :