MVVM pattern for deliving intermediate user input from ViewModel to Model

时间:2015-05-04 19:21:15

标签: c# .net wpf mvvm

I'm new to MVVM and am converting a WinForms project to WPF using the MVVM Light framework. Most introductions to MVVM emphasize that a business model should have no knowledge of a view model. So I'm modifying my business models to support my new view models through the addition of public properties and property-changed events.

But this feels awkward when I just want to get user input that I'm not going to save in the model. In WinForms, I would do it this way in my business model:

dlg.ShowDialog();
string someValue = dlg.SomeValue; 
// Use someValue in a calculation...

Is this really anathema to MVVM:

window.ShowDialog();
string someValue = _ViewModelLocator.MyVm.SomeValue;

It saves me from having to create a public property in the business model for what only really needs to be a local variable.

Thanks for advice & insights.

1 个答案:

答案 0 :(得分:0)

Here's a post I wrote on unit testing a user-interaction (i.e. dialogs).

I recommend using an interface to wrap around your user interaction logic. Leveraging a user interface with delegates will provide an object oriented solution.

The thought process is to unit test your user interaction without user intervention.

In addition, I added this implementation for discovery on Nuget. I believe the class name on that dll that you want to use is called UserInteraction.

public delegate MessageBoxResult RequestConfirmationHandler(object sender, ConfirmationInteractionEventArgs e);

public interface IConfirmationInteraction
{
    event RequestConfirmationHandler RequestConfirmation;
    MessageBoxResult Confirm();
}

public class ConfirmationInteraction : IConfirmationInteraction
{
    #region Events
    public event RequestConfirmationHandler RequestConfirmation;
    #endregion

    #region Members
    object _sender = null;
    ConfirmationInteractionEventArgs _e = null;
    #endregion

    public ConfirmationInteraction(object sender, ConfirmationInteractionEventArgs e)
    {
        _sender = sender;
        _e = e;
    }

    public MessageBoxResult Confirm()
    {
        return RequestConfirmation(_sender, _e);
    }

    public MessageBoxResult Confirm(string message, string caption)
    {
        _e.Message = message;
        _e.Caption = caption;
        return RequestConfirmation(_sender, _e);
    }
}

}

public class ConfirmationInteractionEventArgs : EventArgs
    {
        public ConfirmationInteractionEventArgs() { }

        public ConfirmationInteractionEventArgs(string message, string caption, object parameter = null)
        {
            Message = message;
            Caption = caption;
            Parameter = parameter;
        }

        public string Message { get; set; }
        public string Caption { get; set; }
        public object Parameter { get; set; }
    }