2011-01-24 6 views
8
Events

Je développe une application WPF avec le motif MVVM, RelayCommand, etc. je lis beaucoup sur cette question, mais je ne suis pas clair à:WPF et MVVM. Reliure

Tout ce que je veux faire est de déplacer une forme, comme une ellipse, par exemple, et capturer sa position finale, à mettre dans la base de données.

Mais je ne peux pas lier les événements (MouseLetButtonDown, MouseLeftButtonUp et MouseMove) aux commandes. J'ai lu des comportements attachés, mais j'ai besoin des arguments des événements (MouseButtonEventArgs et MouseEventArgs) pour récupérer la position.

Solution?

Répondre

2

Cela fonctionne pour Silverlight il devrait fonctionner sur WPF (ou au moins il se doit avec des modifications mineures)

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

Vous avez oublié de mentionner que cela utilise le mélange – TigOldBitties

8

Lors de l'écriture d'une application graphique MVVM, il est tentant d'essayer d'envoyer tous les événements dont vous avez besoin sur le modèle de vue. Mais le traitement des arguments d'événement de souris spécifiques à la vue dans une commande est contraire aux principes MVVM et à l'objectif du couplage libre.

La façon de résoudre ce problème est de faire abstraction de l'opération dans une tâche que la vue peut exécuter et de communiquer ses résultats à la vue modèle via des opérations et des données. Si vous voulez exécuter une petite quantité de code dans le code-behind, la police MVVM ne viendra pas prendre vos enfants. Mais un moyen encore meilleur est d'ajouter de l'interactivité aux comportements. Les comportements sont réutilisables morceaux de fonctionnalité sans code-behind qui fonctionnent bien avec le modèle MVVM et les applications qui ont besoin d'interactivité qui nécessiteraient l'ajout de gestionnaires d'événements à votre XAML.

Voir ma réponse ici pour un exemple complet d'un comportement qui utilise les événements de la souris pour faire glisser des objets graphiques:

Avec votre interactivité réalisée par la vue, le point de vue-modèle peut s'en tenir aux données et aux commandes.

+0

Merci beaucoup, c'était exactement ce dont j'avais besoin. Maintenant, je comprends mieux le modèle MVVM. –

0

Vous pouvez trouver XCommand open source CodePlex projet WPF extention ici, xcommand.codeplex.com, ce qui vous permet de lier commande et CommandParameter de tout événement comme MouseMove, MouseLeftButtonDown à tous les éléments de l'interface utilisateur qui hérite de WPF UIElement.

Vous pouvez trouver Windows Store 8 application et fenêtres version de l'application de bureau des bibliothèques de classe ici. Vous voulez que WPFXCommand traite de l'application de bureau WPF. Ici, comment ça marche. Ajouter WPFXCommand.dll comme référence à votre projet de désir.

Ajouter l'espace de noms sur votre fichier XAML comme ci-dessous:

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

Maintenant, vous pouvez lier Commande et CommandParameter à des événements disponibles sur tous les éléments de l'interface utilisateur héritent de WPF UIElement comme ci-dessous:

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

Espérons que cela vous aidera à se débarrasser de l'e vent basé code derrière.