4

I'm a student learning C# with WPF using the MVVM pattern. Recently I have been working on a [art of my application (a custom splash screen) that should not be closed when I don't want it to. I have been searching the web for a good way of doing this without code-behind. Unfortunately after days I still did not find a satisfying way. Then I came to think of a way to do it myself, with help of just one line of code in the constructor of my view. It still makes my code testable and decouples the code from the View. The question is, is there a better way of doing what I'm trying to do:

My interface for my ViewModel

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

The extension for the 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;
                                       }
                                   };
        }
    }
}

The code-behind for the View

public partial class SplashScreen
{
    public SplashScreen()
    {
        InitializeComponent();
        this.PreventCloseViewModel();
    }
}
4

2 回答 2

14

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

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

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

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

于 2013-06-06T22:44:58.953 回答
4

我通常有一个泛型Shell类,它子类化Window并执行以下操作:

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

这样,您放入哪种视图模型都没有关系,只要它实现了将要考虑的接口。

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

于 2013-06-06T22:45:37.733 回答