Отображение диалогов в MVVM и настройка параметров диалога - PullRequest
2 голосов
/ 13 октября 2010

Мне просто интересно, это способ показа диалогов в 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];
    }
}

Если так, как я должен позволять себе говорить об изменении параметров диалогов, которые я показываю.Например, я хочу, чтобы в другом диалоговом окне были другие параметры dialog.something = something_else без добавления большого количества аргументов в мой метод

Ответы [ 2 ]

5 голосов
/ 14 октября 2010

Я думаю, что использование DialogService - это тяжелый подход.Мне нравится использовать Actions / Lambdas для решения этой проблемы.

Ваша модель представления может иметь это как объявление:

public Func<string, string, dynamic> OpenFileDialog { get; set; }

Затем вызывающая сторона создаст модель представления следующим образом:

var myViewModel = new MyViewModel();
myViewModel.OpenFileDialog = (title, filter) =>
{
    var dialog = new OpenFileDialog();
    dialog.Filter = filter;
    dialog.Title = title;

    dynamic result = new ExpandoObject();
    if (dialog.ShowDialog() == DialogResult.Ok) {
        result.Success = true;
        result.Files = dialog.SafeFileNames;
    }
    else {
        result.Success = false;
        result.Files = new string[0];
    }

    return result;
};

Затем вы могли бы назвать это следующим образом:

dynamic res = myViewModel.OpenFileDialog("Select a file", "All files (*.*)|*.*");
var wasSuccess = res.Success;

Такой подход действительно окупается для тестирования.Поскольку ваши тесты могут определять доходность вашей модели представления как угодно:

 myViewModelToTest.OpenFileDialog = (title, filter) =>
{
    dynamic result = new ExpandoObject();
    result.Success = true;
    result.Files = new string[1];
    result.Files[0] = "myexpectedfile.txt";

    return result;
};

Лично я считаю этот подход наиболее упрощенным.Я хотел бы, чтобы мысли других.

5 голосов
/ 13 октября 2010

Отображение самого диалога не должно происходить в ViewModel.Я обычно предоставляю интерфейс службы диалога IDialogServices с соответствующими вызовами методов Dialog.Затем у меня есть один из классов View (обычно MainWindow), реализующий этот интерфейс и выполняющий фактическую логику Show.Это изолирует вашу логику ViewModel от конкретного View и, например, позволяет вам выполнить код модульного тестирования, который хочет открыть диалоговое окно.

Затем основной задачей является внедрение интерфейса службы в ViewModel, которая в этом нуждается.Это проще всего, если у вас есть структура внедрения зависимостей, но вы также можете сделать это с помощью сервис-локатора (статический класс, в котором вы можете зарегистрировать реализации интерфейса) или передать интерфейс в ViewModel через его конструктор (зависит от того, как ваши ViewModelsпостроены.)

...