M-V-VM - Какие-либо Примеры использования команд в ViewModel?

Ваш «логотип1» слишком велик для определенных устройств, и он будет зависать. Переместите его в папку drawable-xxhdpi.

16
задан Community 23 May 2017 в 12:33
поделиться

4 ответа

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

Я обдумал этот вопрос сам в течение некоторого времени и принял довольно прагматическое решение для моей кодовой базы:

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

Что я делал?
Я добавил контроллер для навигации:

public interface INavigation
{
  void NewContent(ViewModel viewmodel);
  void NewWindow(ViewModel viewmodel);
}

Этот контроллер действительно содержит два действия: NewContent () действительно показывает новое содержание в текущем окне, NewWindow () создает новое Окно, заполняет его с содержанием и показывает его.
Конечно, мои viewmodels не имеют никакой подсказки, которые просматривают для показа. Но они действительно знают, какой viewmodel они хотят показать, таким образом, согласно Вашему примеру, когда DeleteCommand выполняется, он назвал бы служебную функцию навигации NewWindow (новый ValidateCustomerDeletedViewModel ()) для показа окна, указав, что 'клиент был удален' (излишество для этого простого messagebox, но будет легко сделать, чтобы специальный навигатор функционировал для простого messageboxes).

Как viewmodel получает сервис навигации?

Мой viewmodel класс имеет свойство для контроллера навигации:

public class ViewModel
{
  public INavigation Navigator { get; set; }
  [...]
}

Когда viewmodel будет присоединен к окну (или безотносительно дисплеев представление), окно установит свойство Navigator, таким образом, viewmodel может назвать его.

Как навигатор создает представление к viewmodel?

У Вас мог быть простой список, которые просматривают для создания, для которого viewmodel, в моем случае я могу использовать простое отражение, так как имена соответствуют:

public static FrameworkElement CreateView(ViewModel viewmodel)
{
  Type vmt = viewmodel.GetType();
  // big bad dirty hack to get the name of the view, but it works *cough*
  Type vt = Type.GetType(vmt.AssemblyQualifiedName.Replace("ViewModel, ", "View, ")); 
  return (FrameworkElement)Activator.CreateInstance(vt, viewmodel);
}

Конечно, для представления нужен конструктор, принимающий viewmodel как параметр:

public partial class ValidateCustomerDeletedView : UserControl
{
  public ValidateCustomerDeletedView(ValidateCustomerDeletedViewModel dac)
  {
    InitializeComponent();
    this.DataContext = dac;
  }
}

Как мое окно похоже?

Простой: мое главное окно действительно реализует интерфейс INavigation и показывает начальную страницу на создании. Лично убедитесь:

public partial class MainWindow : Window, INavigation
{
  public MainWindow()
  {
    InitializeComponent();
    NewContent(new StartPageViewModel());
  }

  public MainWindow(ViewModel newcontrol)
  {
    InitializeComponent();
    NewContent(newcontrol);
  }

  #region INavigation Member
  public void NewContent(ViewModel newviewmodel)
  {
    newviewmodel.Navigator = this;
    FrameworkElement ui = App.CreateView(newviewmodel);
    this.Content = ui;
    this.DataContext = ui.DataContext;
  }

  public void NewWindow(ViewModel viewModel)
  {
    MainWindow newwindow = new MainWindow(viewModel);
    newwindow.Show();
  }
  #endregion
}

(Это действительно работает одинаково хорошо с NavigationWindow и обертыванием представления в Страницу),

Конечно, это является тестируемым, так как контроллер навигации можно дразнить легко.

Я не действительно уверен, является ли это идеальным решением, но оно работает приятно на меня прямо сейчас. Любые идеи и комментарии приветствуются!

3
ответ дан 30 November 2019 в 23:32
поделиться

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

0
ответ дан 30 November 2019 в 23:32
поделиться

Для Вашего удалять случай окна сообщения, я абстрагирую messageboxes через интерфейс. Подобный этому. Я также ввожу эти интерфейсы для своего приложения WPF.

Конструктор

    public MyViewModel(IMessage msg)
    {
      _msg = msg;
    }

Затем в методе удаляют метод на ViewModel... что-то как

    public void Delete()
    {
      if(CanDelete)
      {
        //do the delete 
      }
      else
      {
        _msg.Show("You can't delete this record");
      }
    }

Это сделает это тестируемым, можно включить различные реализации IMessage, которые на самом деле не показывают messagebox. Они могли бы просто распечатать к консоли для тестирования. Очевидно, Ваше приложение WPF могло бы иметь реализацию как

public class MessageBoxQuestion : IMessage
{
   public void Show(string message)
   {
     MessageBox.Show(message);
   }
}

Выполнение этого делает тестирование различных маршрутов (думайте Да/Нет диалоговые окна), очень легкий и прямой. Можно вообразить удалить подтверждение. Вы могли или использовать конкретный экземпляр IMessage, чтобы возвратить true для подтверждения или дразнить контейнер во время Вашего теста.

[Test]
public void Can_Cancel_Delete()
{
  var vm = new ProductViewModel(_cancel);
  ...

}
[Test]
public void Can_Confirm_Delete()
{
  var vm = new ProductViewModel(_yes);
  ...

}

Для Вашего другого вопроса на том, когда использовать Команду, я инстанцирую Добавления Нового или представления Деталей от рассматриваемого Представления. Так же, как Вы имеете в своем примере. Представления только инстанцируют другие Представления в нашем приложении. Я не использую команду в тех случаях. Я действительно однако использую свойства ViewModel родительского представления к дочернему представлению.

public void Object_DoubleClick(object sender, EventArgs e)
{
  var detailView = new DetailView(ViewModel.Product);
  detailView.Show();
}

Надеюсь, это поможет!

1
ответ дан 30 November 2019 в 23:32
поделиться

Один путь состоял бы в том, чтобы использовать объект параметра команды, который может изменить бизнес-слой, и Ваш VM может обработать после команды в выполняемом.

0
ответ дан 30 November 2019 в 23:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: