我正在使用 MVVM 模式、RelayCommand 等开发 WPF 应用程序。我在这个问题上读了很多,但我不清楚:
我要做的就是移动一个形状,例如椭圆,然后捕获它的最终位置,以放入数据库中。
但我无法将事件(MouseLetButtonDown、MouseLeftButtonUp 和 MouseMove)绑定到命令。我已阅读有关附加行为的信息,但我需要事件的参数(MouseButtonEventArgs 和 MouseEventArgs)来检索位置。
解决方案?
在编写 MVVM 图形应用程序时,尝试将所需的所有事件发送到视图模型是很诱人的。但是在命令中处理特定于视图的鼠标事件参数有悖于 MVVM 原则和松散耦合的目标。
解决这个问题的方法是将操作抽象为视图可以执行的任务,然后通过操作和数据将其结果传达回视图模型。如果你想在代码隐藏中执行少量代码来支持这一点,MVVM 警察不会来带你的孩子。但更好的方法是添加与行为的交互性。行为是可重用的功能片段,没有代码隐藏,可以很好地与 MVVM 模式和需要交互性的应用程序配合使用,否则需要将事件处理程序添加到 XAML。
有关使用鼠标事件拖动图形对象的行为的完整示例,请参见我的答案:
通过视图执行的交互,视图模型可以坚持数据和命令。
这适用于 Silverlight,因此它应该适用于 WPF(或者至少应该稍作修改)
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<cmd:EventToCommand Command="{Binding MouseCommand, PassEventArgsToCommand="True", CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
您可以在此处找到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"
现在,您可以将Command和CommandParameter绑定到从 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>
希望这将帮助您摆脱基于事件的代码。