2010-06-22 194 views
6

我发现实际上有两种方法来处理mvvm模式控件上的鼠标事件。使用MVVM模式处理控件上的鼠标事件 - 最佳实践 -

这两种方法实际上是1路:

MVVM光工具包由http://mvvmlight.codeplex.com/

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="SelectionChanged"> 
     <cmd:EventToCommand 
      Command="{Binding SelectionChangedCommand}" 
      CommandParameter="{Binding SelectedItems, 
       ElementName=MyDataGrid}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

与行为的混合interactivity.dll

<i:Interaction.Triggers> 
    <i:EventTrigger EventName=”MouseLeftButtonDown”> 
    <Behaviours:ExecuteCommandAction Command=”{Binding MyCommand}” CommandParameter=”{Binding MyCommandParameter}”/> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

你知道有更好的方法吗?

主持人:为什么我的最后6个xaml代码行看不见? 它们被IE和Iron浏览器吞噬。 请您举报管理员修复该代码脚本吗?它并不经常工作。证明:http://img251.imageshack.us/img251/5236/errorxt.png

+0

在StackOverflow代码中,必须缩进四个空格才能将其识别为代码并正确格式化。我认为你不知道这一点,因为你问的线条根本没有缩进。我编辑你的问题来解决这个问题。编辑器顶部有一个按钮,可让您快速缩进:它的图标是全1和零。 – 2010-06-22 08:57:36

+0

一如既往,我使用零/一个按钮并粘贴代码。 – msfanboy 2010-06-22 09:11:34

+0

然后我猜你的粘贴出了问题,因为它没有在编辑文本框中缩进。我从不再使用零/一个按钮,所以我忘记了它的工作原理。 – 2010-06-22 09:39:18

回答

8

如果您需要在任意位置处理MouseDown,那么这些都是很好的方法。

但是,这些情况通常很少和很远。通常有一个更简单的方法:

  • 你确定你的对象不是真的只是看起来不像按钮的按钮?如果是这样,使它们成为真正的Button对象并对它们进行模板化,以便以您想要的方式查看。
  • 您确定您的对象只是列表中对象的选择区域吗?如果是这样,将容器从ItemsControl更改为ListBox和restyle ListBoxItem以使用选择区域。
  • 您的对象是被选中的图形路径吗?使用其内容是路径本身的ToggleButton。

还有很多其他的例子。事实上,找到MouseDown映射到Command并且没有更简单的方法来执行相同的事情的情况并不常见。

+0

您提到MouseDown explecitly和往往,鼠标点击什么?上述方法对它不好吗?我经常看到带有关于mvvm和事件的附加行为的鼠标点击。但那些我将不得不编写自己的... – msfanboy 2010-06-22 09:35:40

+1

你如何定义“鼠标点击”?在WPF中,这个概念并不存在。你有按钮点击,但没有鼠标“点击”这样的事情:鼠标按钮向下和向上是单独的事件。对于按钮点击,您不需要将Click事件映射到命令的方式,因为Button类已具有可直接使用的Command属性。 – 2010-06-22 09:45:15

+1

对不起,它似乎我的代码片段误导:MouseLeftButtonDown 我从来不想谈论按钮...我知道他们有一个命令属性绑定... – msfanboy 2010-06-25 20:18:22

7

总是有另一种选择。您可以在View的代码隐藏中处理WPF事件,并在ViewModel上调用适当的方法。 MVVM模式不禁止在视图的代码隐藏文件中编写任何代码。

WPF Application Framework (WAF)视图模型示例应用程序演示如何能工作。

2

XCommand开源codeplex项目有更好的方式来处理基于事件的Command/CommandParameter绑定。在这里找到,xcommand.codeplex.com

这里是下面的示例代码:

<Grid> 
    <TextBlock Margin="20,30,20,0" VerticalAlignment="Top" Height="80" x:Name="XTextBlock" 
      Foreground="{Binding FgColor, Mode=TwoWay}" 
      XCmd:MouseMove.Command="{Binding TextBlockPointerMovedCommand}" 
      XCmd:MouseLeftButtonDown.Command="{Binding TextBlockPointerPressedCommand}" 
      XCmd:MouseLeave.Command="{Binding TextBlockPointerExitedCommand}"  
      Text="{Binding Description, Mode=TwoWay}"> 
    </TextBlock> 
    <Grid Grid.Column="1" Background="{Binding BgColor, Mode=TwoWay}" 
      XCmd:MouseMove.Command="{Binding GridPointerMovedCommand}" 
      XCmd:MouseMove.CommandParameter="{Binding ElementName=XTextBlock, Path=Text}" 
      XCmd:MouseLeftButtonDown.Command="{Binding GridPointerPressedCommand}" 
      XCmd:MouseLeftButtonDown.CommandParameter="{Binding ElementName=XTextBlock, Path=Text}" 
      > 
    </Grid> 
</Grid> 

希望这会有所帮助。