返回首页
当前位置: 主页 > WPF > WPF国外资料 >

WPF MVVM – Simple ‘MessageBox.Show’ With Action & Func

时间:2011-08-02 22:14来源:www.deanchalk.me.uk 作者:Dean Chalk 点击:
In the MVVM world, things like message boxes (MessageBox.Show) and Dialogs (open file, save file etc), don't naturally fit. These popups are closely tied to the View part of MVVM, but they can only really be invoked from the ViewModel which will break the
  

  In the MVVM world, things like message boxes (MessageBox.Show) and Dialogs (open file, save file etc), don't naturally fit.

  These popups are closely tied to the ‘View’ part of MVVM, but they can only really be invoked from the ‘ViewModel’ which will break the clean separation in MVVM.

  If you google this issue, you will find a wide range of elaborate solutions, many of which are significant engineering projects in their own right.

  I am a huge fan of implementing simple solutions wherever possible, as verbose code is the number one culprit in un-maintainable projects, so I was keen to find a solution that is simple, robust, elegant and doesnt break the MVVM pattern

  The solution I came up with, is to use generic Action and Func Delegates.

  OK, to illustrate my solution, I have created a new project using the ‘WPF Model-View-ViewModel Toolkit’, (http://wpf.codeplex.com/wikipage?title=WPF%20Model-View-ViewModel%20Toolkit), which installs a project template in VS2008

  Here is my altered ‘MainViewModel'.cs’ class

public class MainViewModel : ViewModelBase
{
    private DelegateCommand exitCommand;
    private Action<string> popup;
    private Func<stringstringbool> confirm;
 
    public MainViewModel(Action<string> popup, Func<stringstringbool> confirm)
    {
        this.popup = popup;
        this.confirm = confirm;
    }
 
    public ICommand ExitCommand
    {
        get
        {
            if (exitCommand == null)
                exitCommand = new DelegateCommand(Exit);
            return exitCommand;
        }
    }
 
    private void Exit()
    {
        if (confirm("Are you sure you want to exit""confirm exit"))
            Application.Current.Shutdown();
    }
}

  As you can see, the MainViewModel’s constructor takes 2 delegates, 1 for popup and 1 for confirm

  Now take a look at App.xaml.cs, where the View and the ViewModel get instantiated

private void OnStartup(object sender, StartupEventArgs args)
{
    // messagebox
    var popup = (Action<string>)(msg => MessageBox.Show(msg));
 
    // confirm box
    var confirm = (Func<stringstringbool>)((msg, capt) => 
        MessageBox.Show(msg, capt, MessageBoxButton.YesNo) == MessageBoxResult.Yes);
 
    Views.MainView view = new Views.MainView();
    view.DataContext = new ViewModels.MainViewModel(popup,confirm);
    view.Show();
}

  If you look closely, you’ll see that my delegates actually map to methods in the static class ‘MessageBox’, which will give us the popups we need. The popup delegate will instantiate a simple message popup, and the confirm delegate will instantiate a message popup with confirm buttons.

  And this is what happens when we click on the Exit menu item (note: this menu is created by default when you create a new project using the toolkit)

  

popup

 

  Now, when we want to run unit tests on our ViewModel, we can just pass in dummy delegates

public void MainViewModelConstructorTest()
{
    var dummyPopup = (Action<string>)((a) => {return;});
    var dummyConfirm = (Func<string,string,bool>)((a,b) => {return true;});
    ViewModels.MainViewModel target = new ViewModels.MainViewModel(dummyPopup, dummyConfirm);
    Assert.Inconclusive("TODO: Implement code to verify target");
}

  本文来自Lee的博客,原文地址:http://www.deanchalk.me.uk/post/WPF-MVVM-e28093-Simple-e28098MessageBoxShowe28099-With-Action-Func.aspx

  
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
最新评论 查看所有评论
发表评论 查看所有评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
推荐内容