8

我正在使用 MVVM 模式、RelayCommand 等开发 WPF 应用程序。我在这个问题上读了很多,但我不清楚:

我要做的就是移动一个形状,例如椭圆,然后捕获它的最终位置,以放入数据库中。

但我无法将事件(MouseLetButtonDown、MouseLeftButtonUp 和 MouseMove)绑定到命令。我已阅读有关附加行为的信息,但我需要事件的参数(MouseButtonEventArgs 和 MouseEventArgs)来检索位置。

解决方案?

4

3 回答 3

8

在编写 MVVM 图形应用程序时,尝试将所需的所有事件发送到视图模型是很诱人的。但是在命令中处理特定于视图的鼠标事件参数有悖于 MVVM 原则和松散耦合的目标。

解决这个问题的方法是将操作抽象为视图可以执行的任务,然后通过操作和数据将其结果传达回视图模型。如果你想在代码隐藏中执行少量代码来支持这一点,MVVM 警察不会来带你的孩子。但更好的方法是添加与行为的交互性。行为是可重用的功能片段,没有代码隐藏,可以很好地与 MVVM 模式和需要交互性的应用程序配合使用,否则需要将事件处理程序添加到 XAML。

有关使用鼠标事件拖动图形对象的行为的完整示例,请参见我的答案:

通过视图执行的交互,视图模型可以坚持数据和命令。

于 2011-01-24T22:12:28.550 回答
2

这适用于 Silverlight,因此它应该适用于 WPF(或者至少应该稍作修改)

<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<cmd:EventToCommand Command="{Binding MouseCommand, PassEventArgsToCommand="True", CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
于 2011-01-24T18:46:37.607 回答
0

您可以在此处找到XCommand开源 codeplex wpf 扩展项目xcommand.codeplex.com,这允许您将诸如 MouseMove、MouseLeftButtonDown 等任何事件的 Command 和 CommandParameter 绑定到从 WPF UIElement 继承的任何 UI 元素。

您可以在此处找到 windows store 8 应用程序和 windows 桌面应用程序版本的类库。您需要处理 WPF 桌面应用程序的 WPFXCommand。在这里,它是如何工作的。添加WPFXCommand.dll作为您想要的项目的参考。

在您的 xaml 文件中添加命名空间,如下所示:

xmlns:XCmd="clr-namespace:WPFXCommand;assembly=WPFXCommand"

现在,您可以将CommandCommandParameter绑定到从 WPF UIElement 继承的任何 UI 元素上的任何可用事件,如下所示:

    <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>

希望这将帮助您摆脱基于事件的代码。

于 2014-04-27T21:05:53.123 回答