最佳实践背后的WPF MVVM代码

本文关键字:WPF MVVM 代码 背后 最佳 | 更新日期: 2023-09-27 18:17:14

我是一名使用MVVM模式学习c#和WPF的学生。最近,我一直在为我的应用程序(一个自定义启动屏幕)设计一个不应该在我不希望它关闭时关闭的艺术。我一直在网上寻找一种没有代码隐藏的好方法。不幸的是,几天后我仍然没有找到一个令人满意的方法。然后,我想到了一种自己完成它的方法,只需在视图的构造函数中编写一行代码。它仍然使我的代码可测试,并将代码与视图解耦。问题是,有没有更好的方法来做我正在做的事情:

我的ViewModel的接口

public interface IPreventCloseViewModel
{
    bool PreventClose { get; set; }
}

View的扩展名

public static class PreventCloseViewModelExtension
{
    /// <summary>
    /// Use this extension method in the constructor of the view.
    /// </summary>
    /// <param name="element"></param>
    public static void PreventCloseViewModel(this Window element)
    {
        var dataContext = element.DataContext as IDisposable;
        if (dataContext is IPreventCloseViewModel)
        {
            element.Closing += delegate(object sender, CancelEventArgs args)
                                   {
                                       if (dataContext is IPreventCloseViewModel)
                                       {
                                           args.Cancel = (dataContext as IPreventCloseViewModel).PreventClose;
                                       }
                                   };
        }
    }
}

View

的后台代码
public partial class SplashScreen
{
    public SplashScreen()
    {
        InitializeComponent();
        this.PreventCloseViewModel();
    }
}

最佳实践背后的WPF MVVM代码

MVVM并不意味着你不能使用代码隐藏。

MVVM意味着您的应用程序逻辑不应该绑定到UI元素。

你可以很好地处理后台代码中的事件(如Window.Closing),并在ViewModel中"发送消息"或执行方法来对其做出反应。

在这里,通过将事件处理程序放在代码后面,您不会破坏MVVM。如果将决定应用程序是否可以关闭的逻辑放在后面的代码中,就会破坏MVVM。这是应用程序逻辑的责任,而应用程序逻辑存在于ViewModels中,而不是Views中。

我通常有一个通用的Shell类,子类Window,并做一些像:

public Shell()
{
    InitializeComponent();
    this.Closing += (s,e) =>
    {
        var canClose = Content as ICanClose;
        if (canClose != null)
            e.Cancel = !canClose.CanClose;
    }
}

这样,不管你放入什么样的视图模型,只要它实现了将被考虑的接口。

不认为外部化逻辑有多大意义,就MVVM模式而言,这很好。