Каков наилучший способ передать событие в ViewModel?

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

В View.xaml:

 

В View.xaml.cs:

 private void SearchResultRefreshed(object sender, EventArgs e) { if (SearchResultRefreshedButton.Command != null) { SearchResultRefreshedButton.Command.Execute(SearchResultGrid.ResultRowCount); } } 

Это работает хорошо, но это выглядит как взломать меня. Мне интересно, есть ли лучший (стандартный) способ сделать это? Я не мог найти примеров, и это то, что я «изобрел» сам.

Используя MVVM, общий способ обработки событий – просто обернуть их в Attached Properties или использовать Attached Events . Ниже приведен пример использования события PreviewKeyDown в Attached Property:

 public static DependencyProperty PreviewKeyDownProperty = DependencyProperty.RegisterAttached("PreviewKeyDown", typeof(KeyEventHandler), typeof(TextBoxProperties), new UIPropertyMetadata(null, OnPreviewKeyDownChanged)); public static KeyEventHandler GetPreviewKeyDown(DependencyObject dependencyObject) { return (KeyEventHandler)dependencyObject.GetValue(PreviewKeyDownProperty); } public static void SetPreviewKeyDown(DependencyObject dependencyObject, KeyEventHandler value) { dependencyObject.SetValue(PreviewKeyDownProperty, value); } public static void OnPreviewKeyDownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { TextBox textBox = dependencyObject as TextBox; if (e.OldValue == null && e.NewValue != null) textBox.PreviewKeyDown += TextBox_PreviewKeyDown; else if (e.OldValue != null && e.NewValue == null) textBox.PreviewKeyDown -= TextBox_PreviewKeyDown; } private static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) { TextBox textBox = sender as TextBox; KeyEventHandler eventHandler = GetPreviewKeyDown(textBox); if (eventHandler != null) eventHandler(sender, e); } 

Обратите внимание, что так же просто (и лучше) использовать ICommand вместо фактического объекта KeyEventArgs который не должен быть действительно в модели представления. Просто создайте Attached Property типа ICommand и вызовите это из этого обработчика TextBox_PreviewKeyDown :

 private static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) { TextBox textBox = sender as TextBox; ICommand command = PreviewKeyDownCommand(textBox); if (command != null && command.CanExecute(textBox)) command.Execute(textBox); } 

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

  

Или если вы использовали предпочтительный метод ICommand :

  

Лично мне никогда не приходилось использовать прикрепленное свойство, чтобы иметь дело с событием элемента управления. В вашем примере элемент управления, который хочет знать, когда «SearchResultRefreshed», а затем информирует ViewModel с помощью скрытого элемента управления … почему ViewModel уже не знает, что результаты были обновлены?

Если результаты появляются из ViewModel в первую очередь, а привязка используется для отображения их внутри вашего элемента управления, то знание о том, что результаты поиска были обновлены, должно управляться вашим ViewModel, а не вашим представлением.

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

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

вот пример, как вы можете это сделать

 public static readonly DependencyProperty DataRefreshedProperty = DependencyProperty.Register( "DataRefreshed", typeof(bool), typeof("typeof yourcontrol here "), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnDataRefreshedChanged) ) ); public bool DataRefreshed { get { return (bool)GetValue(DataRefreshedProperty); } set { SetValue(DataRefreshedProperty, value); } } 

Затем вы можете манипулировать своим свойством, как и любое другое свойство WPF, например SearchResultRefreshed которое определено в вашей модели ViewModel

   

взгляните на следующий учебник, чтобы понять больше dependecyproperty and attachedproperty

  • Где Application.DoEvents () в WPF?
  • В WPF можно фильтровать CollectionViewSource без кода?
  • Как упаковать библиотеку .NET, ориентированную на универсальную платформу Windows?
  • Windows Phone 8.1. Переключение видимости TextBlock в DataTemplate
  • Являются ли "{Binding Path =.}" И "{Binding}" действительно равными
  • WPF: имя не существует в пространстве имен
  • Навигация по страницам с помощью MVVM в приложении Store
  • Пример использования гиперссылки в WPF
  • Стиль кнопки WPF C #
  • Связывание в текстовом столбце таблицы данных WPF
  • Как я могу создать границу и строку заголовка windows в WPF?
  • Давайте будем гением компьютера.