最佳实践背后的WPF MVVM代码

时间:2013-06-06 22:38:56

标签: c# wpf mvvm code-behind

我是一名学生使用MVVM模式学习使用WPF的C#。最近我一直致力于[我的应用程序的艺术(自定义启动画面),当我不希望它时,不应该关闭它。 我一直在网上寻找一个没有代码隐藏的好方法。不幸的是,几天后我仍然没有找到令人满意的方式。 然后我开始想到一种方法,在我的视图的构造函数中只有一行代码的帮助。它仍然使我的代码可测试并将代码与View分离。问题是,有没有更好的方法来做我想做的事情:

我的ViewModel界面

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

视图的扩展名

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();
    }
}

2 个答案:

答案 0 :(得分:14)

MVVM并不意味着您不能使用Code-Behind。

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

您可以很好地处理后面的代码中的事件(例如Window.Closing),以及“发送消息”或在ViewModel中执行方法以对此作出反应。

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

答案 1 :(得分:4)

我通常有一个通用的Shell类,其子类为Window,并执行如下操作:

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

这样,如果它实现了将被考虑的接口,那么放入哪种视图模型并不重要。

在外部化逻辑方面没有多大意义,就MVVM模式而言,这很好。