Liens
RelayCommand
A la différence des RoutedCommand, elle permet d'exécuter directement le délégué associé.
Le code source est disponible dans MSDN Magazine de Février 2009.
Relaying Command Logic
|
<Button Command="{Binding Path=MyCmd}"
CommandParameter="MonParamètre"/>
|
|
public ICommand MyCmd { get; private set; }
MyCmd = new RelayCommand<int>(MyCmdAction, MyCmdCanExecute);
private void MyCmdAction(object obj) { ... }
private bool MyCmdCanExecute(object obj) { ... }
// avec des méthodes anonymes
MyCmd = new RelayCommand<int>(param => { ... }, param => { ... });
// version compacte
private ICommand _myCmd;
public ICommand MyCmd
{
get
{
return _myCmd
?? (_myCmd = new RelayCommand<int>(
param => { ... },
param => { ... }));
}
}
// version compacte sans paramètres
private ICommand _myCmd;
public ICommand MyCmd
{
get
{
return _myCmd
?? (_myCmd = new RelayCommand(
() => { ... }));
}
}
|
Multi-paramètres
|
<xxx xmlns:ConverterNameSpace="clr-namespace:MonNameSpace.MyCmdConverterClass">
<xxx.Resources>
<ConverterNameSpace:MyCmdConverterClass x:Key="MyCmdConverterKey" />
</xxx.Resources>
<Button Command="{Binding Path=ViewModel.MyCmd}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource ResourceKey=MyCmdConverterKey}">
<Binding Path="." />
<Binding RelativeSource="{RelativeSource AncestorType=TextBlock}" Path="Text" />
</MultiBinding>
</Button.CommandParameter>
</Button>
|
|
namespace MonNameSpace
{
public class MyCmdConverterClass : IMultiValueConverter
{
#region IMultiValueConverter Membres
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// on ne peut retourner directement values sinon une fois dans la méthode Execute le tableau d'object ne contient plus que des null
return values.ToArray();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
}
|
|
RelayCommand ne prend qu'un seul paramètre pour execute. |
Rafraichir les commandes
Utile dans le cas où CommandManager n'a pas pu déterminer si la cible de la Commande a changé. Ce qui est souvent le cas si c'est un thread autre que le thread graphique qui modifie le cible. MSDN
|
// Force l'appel de l'event CanExecute sur toutes les Commandes.
CommandManager.InvalidateRequerySuggested();
|
Command vs Event
- Event
- Command
Utilise un attached behavior pour lier un évènement à une commande.
La commande se trouve dans une classe statique pour faciliter son accès.
|
namespace AutreNamespace
{
public static class MaClasse // probablement la fenêtre
{
public static RoutedCommand MaCommande = new RoutedCommand();
}
}
|
On attrape l’événement lancé par la RoutedCommand et on exécute le code que l'on veut.
|
<Window x:Class="CurrentNamespace.MainWindow"
xmlns:autrens="clr-namespace:AutreNamespace">
<Window.CommandBindings>
<CommandBinding Command="{x:Static Member=autrens:MaClasse.MaCommande}"
Executed="MaCommandeExecuted"
CanExecute="MaCommandeCanExecute"/>
</Window.CommandBindings>
|
Lance un RoutedEvent qui va remonter l'arbre visuel jusqu'à trouver un CommandBinding.
On lie le bouton à la commande.
|
<UserControl xmlns:autrens="clr-namespace:AutreNamespace">
<Button Command="{x:Static autrens:MaClasse.MaCommande}"
CommandParameter="{Binding Path=.}" />
|
|
namespace CurrentNamespace
{
public partial class MainWindow : Window
{
private void MaCommandeExecuted(object sender, ExecutedRoutedEventArgs e)
{
// e.Parameter contient le paramètre de la commande
// e.Source contient le composant graphique branché à la commande
}
private void MaCommandeCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
}
}
|
Routed Events
Ils possèdent une des trois stratégie de routing suivante:
Direct |
même fonctionnement que dans Windows form (MouseEnter)
|
Bubbling |
part de l’élément dont l'evt est originaire et remonte l'arbre visuel (ButtonClick)
|
Tunneling |
part de la fenêtre principale et descend l'arbre visuel jusqu'à l'élément cible (Preview*)
|