c# - 将事件传递给 ViewModel 的最佳方式是什么?

标签 c# wpf xaml mvvm

案例是:我有一个控件的事件,我希望我的 ViewModel 对其使用react。目前,我正在通过执行不可见按钮的命令来执行此操作,如下例所示。

在 View.xaml 中:

<Control x:Name="SearchResultGrid" ... DataRefreshed="SearchResultRefreshed" />
<Button x:Name="SearchResultRefreshedButton" Visibility="Collapsed" Command="{Binding SearchResultRefreshedCommand}" />

在 View.xaml.cs 中:

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

这很好用,但对我来说它看起来像是一个 hack。我想知道是否有更好的(标准)方法来做到这一点?我找不到任何例子,这就是我自己“发明”的。

最佳答案

使用 MVVM,处理事件的一般方法是简单地将它们包装在 Attached Properties 中, 或使用 Attached Events .以下是在附加属性中使用 PreviewKeyDown 事件的示例:

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 对象同样容易(而且更好),后者实际上不应出现在 View 模型中。只需创建一个 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);
}

无论哪种方式,它都会像这样使用:

<TextBox TextBoxProperties.PreviewKeyDown="SomeKeyEventHandler" />

或者,如果您使用首选的 ICommand 方法:

<TextBox TextBoxProperties.PreviewKeyDownCommand="{Binding SomeCommand}" />

关于c# - 将事件传递给 ViewModel 的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21285577/

相关文章:

c# - Web Api 2 中的 Mvc 样式参数绑定(bind)?

wpf - 将窗口继承到另一个窗口xaml

c# - 使用属性... INotifyPropertyChanged

xaml - 无法访问 Silverlight 类库中的字体资源

转换网格布局

c# - 具有静态工厂方法的 AutoMapper

c# - 如何在 .NET 应用程序中隐藏加密 key ?

c# - 在编译后将属性注入(inject) .NET 类

c# - 使用 MVVM 单击按钮时对列表框进行排序

c# - 在 int 中设置特定位