Правильный способ обработки команд, которые полагаются на несколько моделей представлений - PullRequest
0 голосов
/ 31 января 2019

Я относительно новичок в WPF и MVVM и пытаюсь понять, как правильно использовать команды, когда они имеют зависимости в более чем 1 модели представления.

Несколько примеров:

  • В моем текущем приложении у меня есть RelayCommand, который вызывает действие сохранения в паре разных моделей представлений (они пишут пару разных файлов).В настоящее время я занимаюсь этим с помощью мессенджера mvvmlight, чтобы отправить сообщение этим моделям представлений, чтобы заставить их сделать сохранение, что, я думаю, является правильным способом сделать это, поскольку избегает необходимости предоставлять какой-либо делегат или событие для / нате модели просмотра.
  • У меня есть RelayCommand в модели представления, которая имеет метод CanExecute, который зависит от состояния двух других моделей представления.В настоящее время я обработал это через мессенджер mvvmlight, а также внес изменения в моделях представления, метод CanExecute зависит от сообщения о том, что их состояние теперь допустимо для операции.Это кажется грязным, но единственной альтернативой, которую я мог придумать, было использование делегата или события, эффективно объединяющих модели представлений, которых, я считаю, следует избегать.

Существует ли какой-то общепринятый способ решенияэто то, чего мне не хватает?

1 Ответ

0 голосов
/ 31 января 2019

Как правило, слой модели представления должен иметь отношение 1: 1 к вашему виду, не должно быть веских оснований для существования функции «Сохранить» в модели представления, которая затем вызывается другой моделью представления.

То, что вы должны делать, это помещать эту логику в службу, т.е. что-то вроде этого:

public interface ISerializationService
{
    void Save(SomeData data);
}

Затем вам нужна реализация для этой службы, которая выполняет реальную работу:

public class SerializationService : ISerializationService
{
    void Save(SomeData data)
    {
        // actual save happens here
    }
}

Ваши модели представлений должны содержать свойства, указывающие на экземпляры этих служб:

public class MyViewModel : ViewModelBase
{
    [Inject]
    public ISerializationService SerializationService { get; set; }

    // called when the user clicks a button or something
    private void ButtonClickCommand()
    {
        this.SerializationService.Save(this.SomeData);
    }
}

Остается только один вопрос: «Что задает значение SerializationService?», И для этого вам нуженструктура внедрения зависимости.Существует множество других возможностей, MVVMLight устанавливает их сам, но Ninject является стандартом де-факто.При правильной реализации среда внедрения создаст для вас все модели представлений, а затем «внедрит» зависимости, т. Е. Ваше свойство SerializationService типа ISerializationService будет инициализировано экземпляром вашего класса SerializationService (который вслучай, подобный этому, также будет настроен как одноэлементный).

Внедрение зависимостей требует немного усилий, чтобы разобраться, но как только вы начнете использовать его, вы никогда не оглядываетесь назад.Это облегчает полное разделение проблем, избавляя от необходимости передавать указатели на все по всей вашей архитектурной иерархии.

...