在WPF的MVVM設計模式中,一個常見的挑戰是如何從ViewModel關閉視圖(例如,窗體)。 ViewModel通常負責管理業務邏輯,而視圖負責使用者介面(UI)顯示。
根據設計,ViewModel不應該直接了解視圖。這確保了關注點分離,並允許UI獨立性。但是,關閉窗體需要存取視圖,這可能是個問題。
傳統的CodeBehind方法: 這涉及將關閉窗體的程式碼放在視圖的codebehind檔案中。這違反了MVVM模式,並在視圖和ViewModel之間引入了耦合。
帶有樣式觸發器的附加屬性: 可以在窗體上定義一個附加屬性,並使用樣式觸發器在設定附加屬性時關閉窗體。雖然此解決方案符合MVVM原則,但它涉及額外的程式碼,並且可能很麻煩。
可以建立一個名為DialogCloser的自訂附加屬性來簡化此過程。此屬性採用一個bool?參數,表示窗體的DialogResult。當此屬性的值被設定時,它會自動設定窗體所包含的Window物件的DialogResult屬性。
<code class="language-csharp">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); } }</code>
要使用此屬性,只需將其套用至XAML視圖中的Window元素:
<code class="language-xml"><Window ... xc:DialogCloser.DialogResult="{Binding DialogResult}" xmlns:xc="clr-namespace:ExCastle.Wpf"></Window></code>
在ViewModel中,將DialogResult屬性綁定到一個布林屬性:
<code class="language-csharp">public class MyViewModel : INotifyPropertyChanged { ... private bool? _dialogResult; public bool? DialogResult { get { return _dialogResult; } set { _dialogResult = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DialogResult))); } } ... }</code>
當在ViewModel中設定DialogResult屬性時,DialogCloser附加屬性會自動更新包含的Window物件的DialogResult,從而有效地關閉表單。
以上是如何從 MVVM 中的 ViewModel 關閉 WPF 表單?的詳細內容。更多資訊請關注PHP中文網其他相關文章!