Search code examples
c#wpfmvvmmvvm-foundation

Showing Dialogs in MVVM & Setting dialog options


I am just wondering is this the way to show dialogs in MVVM?

public ICommand OpenFileCommand
{
    get
    {
        if (_openFileCommand == null) {
            _openFileCommand = new RelayCommand(delegate
            {
                var strArr = DialogsViewModel.GetOpenFileDialog("Open a file ...", "Text files|*.txt | All Files|*.*");
                foreach (string s in strArr) {
                    // do something with file
                }
            });
        }
        return _openFileCommand;
    }
}

public class DialogsViewModel {
    public static string[] GetOpenFileDialog(string title, string filter)
    {
        var dialog = new OpenFileDialog();
        dialog.Title = title;
        dialog.Filter = filter;
        dialog.CheckFileExists = true;
        dialog.CheckPathExists = true;
        dialog.Multiselect = true;
        if ((bool)dialog.ShowDialog()) {
            return dialog.SafeFileNames;
        }
        return new string[0];
    }
}

If so how should I allow myself to say modify the options on dialogs I am showing. Example, I want another dialog to have different dialog options dialog.something = something_else without adding alot of arguments to my method


Solution

  • Showing the dialog itself should not happen in a ViewModel. I usually provide a dialog service interface IDialogServices, with appropriate Dialog method calls. I then have one of the View classes (typically the MainWindow) implement this interface and perform the actual Show logic. This isolates your ViewModel logic from the specific View and, for instance, allows you to unit test code that wants to open a dialog.

    The main task then is injecting the service interface into the ViewModel that needs it. This is easiest if you have a dependency-injection framework, but you can also do this with a service-locator (a static class where you can register interface implementations) or pass the interface to the ViewModel through its constructor (depends on how your ViewModels are constructed.)