30

嗨,我最近研究了 WPF 并开始学习事件和命令。我通常在按钮单击时使用命令,这会导致方法在我的“视图模型”中运行。

是否可以通过使用命令使 Button 对任何其他事件(例如 MouseOver 事件)做出反应?或者在这种情况下会使用 WPF 事件吗?

如果要使用 WPF 事件,那么事件处理程序实现是否应该只调用视图模型中的一个方法来保持关注点分散?

4

2 回答 2

13

这是一个公平的问题,也是 MVVM 架构领域中一个常见但“已解决”(有争议)的问题。如果您使用的是 MVVM 框架,您可能会发现类似于 EventToCommand Behavior 的内容,这里是 MVVM Light Toolkit 中的示例。

简而言之,这允许您将事件映射到命令绑定,如下所示:

<Rectangle Fill="White"
       Stroke="Black"
       Width="200"
       Height="100">
<i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseEnter">
        <cmd:EventToCommand Command="{Binding TestCommand,
                                      Mode=OneWay}"
           CommandParameter="{Binding Text,
                              ElementName=MyTextBox,
                              Mode=OneWay}"
           MustToggleIsEnabledValue="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>

更新:

这个问题还有另外两个“合理”的解决方案:

一个使用现在被认为是遗留的“AttachedCommandBehavior”扩展在这里找到。

另一个有点刺激,但可行。

  1. 纯粹在视图中通过事件捕获命令。
  2. 查询控件的DataSource Step
  3. 获取表示您的命令的字符串绑定目标标识符(可能在视图上使用 const 字符串)
  4. 通过反射在视图模型上调用您的命令并传入命令参数。

这看起来很恶心,但我相当肯定它实际上比仅使用传统的命令绑定要快一些。为了确定我需要查看 IL,我认为在这种情况下这并不重要。

/更新

然而,我想指出,这并不总是理想的情况。我发现,我经常使用 EventToCommand 来解决设计问题。请考虑以下几点:

  • 使用事件和代码来处理用户界面相关的行为。
  • 如果合适,请考虑创建具有命令绑定的自定义控件,特别是如果您发现自己使用命令来封装事件驱动的行为来设置绑定数据,然后反映在视图中。(即基于接近控件或类似的东西设置透明度值)
  • EventToCommand 很可能只用于处理“类似命令”的事件(双击等)而不是反应事件(鼠标悬停)。然而,没有什么能阻止这一点。按照您认为合适的方式实施。

最重要的也许是你记得你是开发者。指导方针本身并不能解决问题,但考虑指导方针可能会使问题的解决方案变得明显。

于 2011-05-23T14:55:57.373 回答
6

你可能想看看这篇文章:

WPF 命令与事件的优点/缺点

其中讨论了事件和命令的不同用法。

至于其他事件的命令,您应该看看EventToCommand作为MVVMLight Toolkit的一部分,它允许您将任何事件附加到视图模型中的命令。非常有用,特别是如果您已经在使用 MVVM Light(我强烈推荐)。

于 2011-05-23T14:50:55.933 回答