WPF and MVVM. Binding Events

删除回忆录丶 提交于 2019-11-29 13:37:09
Rick Sladkey

When writing an MVVM graphical application, it is tempting to try to send all the events you need over to the view-model. But processing view-specific mouse event args in a command is contrary to MVVM principles and the goal of loose-coupling.

The way to solve this problem is to abstract the operation into a task that the view can perform and then to communicate its results back to the view-model via operations and data. If you want to perform a small amount of code in the code-behind to support this, the MVVM police will not come and take your children. But an even better way is to add interactivity with behaviors. Behaviors are re-usable pieces of functionality with no code-behind that work well with the MVVM pattern and applications that need interactivity that would otherwise require adding event handlers to your XAML.

See my answer here for a complete example of a behavior that uses mouse events for dragging graphical objects:

With your interactivity performed by the view, the view-model can stick to data and commands.

paxx

This works for Silverlight so it should work on WPF (or at least it should with minor modifications)

<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<cmd:EventToCommand Command="{Binding MouseCommand, PassEventArgsToCommand="True", CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>

You can find XCommand open source codeplex wpf extention project here, xcommand.codeplex.com, this allows you to bind Command and CommandParameter of any events like MouseMove, MouseLeftButtonDown to any UI elements that inherits from WPF UIElement.

You can find windows store 8 application and windows desktop application version of class libraries here. You want WPFXCommand that deals with WPF desktop application. Here, how it works. Add WPFXCommand.dll as reference to your desire project.

Add the namespace on your xaml file as below:

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

Now, you can bind Command and CommandParameter to any available events on any UI elements inherit from WPF UIElement as below:

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

Hope this will help you to get rid of event based code behind.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!