WPF MVVM Проблемы с представлением - PullRequest
2 голосов
/ 20 июня 2011

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

  1. Я использую DataTemplate для ViewModel, но я хочу, чтобы конкретный элемент управления был сфокусирован на клавиатуре.
  2. Как мне сфокусировать определенный элемент управления после выполнения ICommand.
  3. Как мне переместить фокус на неподтвержденный элемент управления.
  4. Есть ли способ разделить DataTemplate в зависимости от значения свойства ViewModel.
  5. Как я могу проверить все элементы управления перед ICommand
  6. Есть ли другой лучший способ запросить подтверждение у ViewModel с помощью MessageBox

С уважением, Mitan

Ответы [ 3 ]

1 голос
/ 20 июня 2011

Я настоятельно рекомендую вам взглянуть на caliburn (или caliburn.micro ), который предоставляет различные интерфейсы UImanager, чтобы ваша модель представления могла делать такие вещи, не теряя тестируемость устройства.

1 голос
/ 20 июня 2011

Вопрос 1:

Непонятно, что вы имеете в виду / хотите. Обычно TabIndex управляет потоком фокуса в вашем приложении, однако с помощью Silverlight его не так легко настроить, как в формах Windows. Silverlight также хорошо выполняет автоматическую настройку последовательности вкладок.

Однако следует помнить, что все элементы управления, наследуемые от Control, по умолчанию получают фокус. Это включает в себя некоторые элементы управления, которые могут использоваться в качестве контейнера для других элементов управления (например, ContentControl). Такое поведение может привести к нежелательным последствиям. Используйте свойство IsTabStop, чтобы удалить эти элементы управления из последовательности вкладок.

Вопрос 2:

Ну, это зависит от того, насколько развязано ваше приложение (чем больше оно отделено, тем лучше). Подход @ pchajer's - один из способов сделать это, однако он связывает представление с моделью представления, и это - хотя и абстрагируется через интерфейс - ИМХО не является хорошей идеей по следующим причинам:

  1. Обычно модель представления извлекается из локатора, чтобы обеспечить смешиваемость. Теперь, если мне придется использовать код для передачи View в ViewModel, это может сломать его. Лучше было бы, если бы его можно было внедрить в ViewModel через параметр конструктора, и тогда он сломал бы локатор.
  2. Код становится менее тестируемым, поскольку теперь он зависит от представления. Чтобы сделать его тестируемым, вам нужно внедрить реализацию IView в ViewModel, и это снова ломает локатор.

Поэтому я бы посоветовал вам использовать Messaging для отправки сообщения вашему представлению после завершения команды. Затем вы можете установить фокус в обработчике сообщений. Однако помните, что вам, возможно, придется использовать Dispatcher, поскольку обработчик сообщений может выполняться в отдельном потоке.

Вопрос 3:

Вы можете перехватить BindingValidationError на элементе управления, а затем установить фокус. Снова осознайте возможные проблемы с многопоточностью.

Вопрос 4:

Не уверен, но если вы имеете в виду, что вы хотите использовать разные DataTemplates в зависимости от того, имеет ли свойство определенное значение или нет, TemplateSelector может вам помочь. См http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-a-datatemplateselector.

Вопрос 5:

Элементы управления проверяются при срабатывании события изменения свойства, обычно для события потерянного фокуса. Ваша модель / ViewModel может реализовать IDataError для выполнения проверки, и вы можете получить доступ к этому значению из метода CanExecute, связанного с вашей командой. Однако вам следует постараться как можно быстрее сохранить код в методе CanExecute, так как этот метод вызывается довольно часто.

Вопрос 6:

Вы можете реализовать свое собственное окно, которое предоставляет пользовательский макет. Тем не менее, использовать окно сообщения намного проще. Опять же, вам следует подумать об использовании службы обмена сообщениями или диалогового сервиса (например, http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/) для разделения вашего View и ViewModel. На самом деле в MVVMLight есть даже DialogMessage.

1 голос
/ 20 июня 2011

Чтобы установить фук на контроль, используйте codebehind. MVVM не говорит, не используйте codebehind.

Напишите метод в коде для установки фокуса и вызовите этот метод из модели представления.

Пример

public interface IView
{
  void setFoucs();
}

//Code Behind
public class MyWindow : Window, IView
{
  public void SetFoucs()
  {
    MyControl.Focus();
  }
}

public class ViewModel
{
  public IView _view { get; set; }
  public ViewModel(IView view)
  {
   _view = view;
  }

  public void SomeMethod()
  {
   _view.SetFocus();
  }

}

Для вопроса № 4 - я думаю, что вы хотите выбрать конкретную табличку с данными на основе вашей логики. Для этого используйте класс DataTemplateSelector.

http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-a-datatemplateselector

...