Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
La commande est un mécanisme d’entrée dans Windows Presentation Foundation (WPF) qui fournit une gestion des entrées au niveau sémantique supérieur à l’entrée de l’appareil. Voici quelques exemples de commandes : les opérations copier, couper et coller trouvées sur de nombreuses applications.
Cette vue d’ensemble définit les commandes qui se trouvent dans WPF, les classes qui font partie du modèle de commande et comment utiliser et créer des commandes dans vos applications.
Cette rubrique contient les sections suivantes :
Qu’est-ce que les commandes
Les commandes ont plusieurs objectifs. Le premier objectif est de séparer la sémantique et l’objet qui appelle une commande de la logique qui exécute la commande. Cela permet à plusieurs sources disparates d’appeler la même logique de commande et de personnaliser la logique de commande pour différentes cibles. Par exemple, les opérations d’édition Copie, Couper et Coller, qui se trouvent dans de nombreuses applications, peuvent être appelées à l’aide de différentes actions utilisateur si elles sont implémentées à l’aide de commandes. Une application peut permettre à un utilisateur de couper des objets ou du texte sélectionnés en cliquant sur un bouton, en choisissant un élément dans un menu ou en utilisant une combinaison de touches, telle que Ctrl+X. En utilisant des commandes, vous pouvez lier chaque type d’action utilisateur à la même logique.
Un autre objectif des commandes est d’indiquer si une action est disponible. Pour continuer l’exemple de coupe d’un objet ou d’un texte, l’action n’a de sens que lorsque quelque chose est sélectionné. Si un utilisateur tente de couper un objet ou du texte sans avoir sélectionné quoi que ce soit, rien ne se produirait. Pour indiquer cela à l’utilisateur, de nombreuses applications désactivent les boutons et les éléments de menu afin que l’utilisateur sache s’il est possible d’effectuer une action. Une commande peut indiquer si une action est possible en implémentant la CanExecute méthode. Un bouton peut s’abonner à l’événement CanExecuteChanged et être désactivé si CanExecute cette propriété est retournée false
ou activée si CanExecute elle est retournée true
.
La sémantique d’une commande peut être cohérente entre les applications et les classes, mais la logique de l’action est spécifique à l’objet particulier. La combinaison de touches Ctrl+X appelle la commande Cut dans les classes de texte, les classes d’images et les navigateurs Web, mais la logique réelle pour effectuer l’opération Cut est définie par l’application qui effectue la coupe. A RoutedCommand permet aux clients d’implémenter la logique. Un objet texte peut couper le texte sélectionné dans le Presse-papiers, tandis qu’un objet image peut couper l’image sélectionnée. Lorsqu’une application gère l’événement Executed , elle a accès à la cible de la commande et peut prendre les mesures appropriées en fonction du type de la cible.
Exemple de commande simple dans WPF
La façon la plus simple d’utiliser une commande dans WPF consiste à utiliser un prédéfini RoutedCommand à partir de l’une des classes de bibliothèque de commandes ; utiliser un contrôle qui prend en charge nativement la gestion de la commande et utiliser un contrôle qui prend en charge nativement l’appel d’une commande. La Paste commande est l’une des commandes prédéfinies dans la ApplicationCommands classe. Le TextBox contrôle a une logique intégrée pour gérer la commande Paste. Et la MenuItem classe prend en charge nativement l’appel de commandes.
L'exemple suivant montre comment configurer un MenuItem de manière à appeler la Paste commande sur un TextBox lors du clic, en supposant que le TextBox a le focus du clavier.
<StackPanel>
<Menu>
<MenuItem Command="ApplicationCommands.Paste" />
</Menu>
<TextBox />
</StackPanel>
// Creating the UI objects
StackPanel mainStackPanel = new StackPanel();
TextBox pasteTextBox = new TextBox();
Menu stackPanelMenu = new Menu();
MenuItem pasteMenuItem = new MenuItem();
// Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem);
mainStackPanel.Children.Add(stackPanelMenu);
mainStackPanel.Children.Add(pasteTextBox);
// Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste;
// Setting the command target to the TextBox
pasteMenuItem.CommandTarget = pasteTextBox;
' Creating the UI objects
Dim mainStackPanel As New StackPanel()
Dim pasteTextBox As New TextBox()
Dim stackPanelMenu As New Menu()
Dim pasteMenuItem As New MenuItem()
' Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem)
mainStackPanel.Children.Add(stackPanelMenu)
mainStackPanel.Children.Add(pasteTextBox)
' Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste
Quatre concepts principaux dans la commande WPF
Le modèle de commande routé dans WPF peut être divisé en quatre concepts principaux : la commande, la source de commande, la cible de commande et la liaison de commande :
La commande est l’action à exécuter.
La source de commande est l’objet qui appelle la commande.
La cible de commande est l’objet sur lequel la commande est exécutée.
La liaison de commande est l’objet qui mappe la logique de commande à la commande.
Dans l’exemple précédent, la commande Paste est la commande, MenuItem est la source de commande, TextBox est la cible de commande et la liaison de commande est fournie par le contrôleur TextBox. Il est important de noter qu'il n'est pas toujours vrai que le CommandBinding est fourni par le contrôle qui appartient à la classe cible de commande. Souvent, le CommandBinding développeur de l’application doit créer l’élément, ou celui-ci CommandBinding peut être attaché à un ancêtre de la cible de commande.
Commandes
Les commandes dans WPF sont créées en implémentant l’interface ICommand . ICommand expose deux méthodes, Executeet CanExecute, et un événement, CanExecuteChanged. Execute effectue les actions associées à la commande. CanExecute détermine si la commande peut s’exécuter sur la cible de commande actuelle. CanExecuteChanged est déclenché si le gestionnaire de commandes qui centralise les opérations de commande détecte une modification dans la source de commande qui peut invalider une commande qui a été déclenchée, mais qui n’est pas encore exécutée par la liaison de commande. L’implémentation WPF de ICommand est la RoutedCommand classe et est le focus de cette vue d’ensemble.
Les principales sources d’entrée dans WPF sont la souris, le clavier, l’encre et les commandes routées. Les entrées orientées davantage vers l'appareil utilisent un RoutedEvent pour notifier des objets dans une page d’application qu’un événement d’entrée s’est produit. Un RoutedCommand n’est pas différent. Les méthodes Execute et CanExecute d’un RoutedCommand ne contiennent pas la logique d’application de la commande ; elles déclenchent plutôt des événements routés qui se propagent et se diffusent dans l’arborescence d’éléments jusqu’à ce qu’ils rencontrent un objet avec un CommandBinding. Le CommandBinding contient les gestionnaires de ces événements, et ce sont eux qui exécutent la commande. Pour plus d’informations sur le routage des événements dans WPF, consultez Vue d’ensemble des événements routés.
La méthode Execute sur un RoutedCommand déclenche les événements PreviewExecuted et Executed sur la cible de commande. La méthode CanExecute sur un RoutedCommand déclenche les événements CanExecute et PreviewCanExecute sur la cible de commande. Ces événements se propagent et remontent dans l’arborescence d’éléments jusqu’à ce qu’ils rencontrent un objet qui possède un CommandBinding pour cette commande spécifique.
WPF fournit un ensemble de commandes routées courantes réparties entre plusieurs classes : MediaCommands, , ApplicationCommandsNavigationCommands, , ComponentCommandset EditingCommands. Ces classes se composent uniquement des RoutedCommand objets et non de la logique d'implémentation de la commande. La logique d’implémentation est la responsabilité de l’objet sur lequel la commande est exécutée.
Sources de commandes
Une source de commande est l’objet qui appelle la commande. Exemples de sources de commandes : MenuItem, Buttonet KeyGesture.
Les sources de commande dans WPF implémentent généralement l’interface ICommandSource .
ICommandSource expose trois propriétés : Command, CommandTargetet CommandParameter:
Command est la commande à exécuter lorsque la source de commande est appelée.
CommandTarget est l’objet sur lequel exécuter la commande. Il est à noter que dans WPF, CommandTarget sur ICommandSource n'est applicable que lorsque ICommand est un RoutedCommand. Si le CommandTarget paramètre est défini sur un ICommandSource et que la commande correspondante n’est pas un RoutedCommand, la cible de commande est ignorée. Si le CommandTarget paramètre n’est pas défini, l’élément avec focus clavier est la cible de commande.
CommandParameter est un type de données défini par l’utilisateur utilisé pour transmettre des informations aux gestionnaires implémentant la commande.
Les classes WPF qui implémentent ICommandSource sont ButtonBase, MenuItem, Hyperlinket InputBinding. ButtonBase, MenuItem et Hyperlink invoquent une commande lorsqu'ils sont cliqués, et un InputBinding invoque une commande lorsque le InputGesture associé est effectué.
L’exemple suivant montre comment utiliser un MenuItem dans une ContextMenu source de commande pour la Properties commande.
<StackPanel>
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Properties" />
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
StackPanel cmdSourcePanel = new StackPanel();
ContextMenu cmdSourceContextMenu = new ContextMenu();
MenuItem cmdSourceMenuItem = new MenuItem();
// Add ContextMenu to the StackPanel.
cmdSourcePanel.ContextMenu = cmdSourceContextMenu;
cmdSourcePanel.ContextMenu.Items.Add(cmdSourceMenuItem);
// Associate Command with MenuItem.
cmdSourceMenuItem.Command = ApplicationCommands.Properties;
Dim cmdSourcePanel As New StackPanel()
Dim cmdSourceContextMenu As New ContextMenu()
Dim cmdSourceMenuItem As New MenuItem()
' Add ContextMenu to the StackPanel.
cmdSourcePanel.ContextMenu = cmdSourceContextMenu
cmdSourcePanel.ContextMenu.Items.Add(cmdSourceMenuItem)
' Associate Command with MenuItem.
cmdSourceMenuItem.Command = ApplicationCommands.Properties
En règle générale, une source de commande écoute l’événement CanExecuteChanged . Cet événement informe la source de commande que la capacité de la commande à s’exécuter sur la cible de commande actuelle peut avoir changé. La source de commande peut interroger l’état actuel de RoutedCommand en utilisant la méthode CanExecute. La source de commande peut ensuite se désactiver si la commande ne peut pas s’exécuter. Par exemple, il s’agit du grisement d’un MenuItem lorsque une commande ne peut pas être exécutée.
Un InputGesture peut être utilisé comme source de commande. Deux types de gestes d'entrée dans WPF sont les KeyGesture et MouseGesture. Vous pouvez considérer un KeyGesture raccourci clavier, tel que Ctrl+C. Un KeyGesture est composé d'un Key et d'un ensemble de ModifierKeys. Un MouseGesture est composé d’un MouseAction et d’un ensemble facultatif de ModifierKeys.
Pour qu'une InputGesture puisse agir comme source de commande, elle doit être associée à une commande. Il existe quelques façons d’y parvenir. Une façon est d’utiliser un InputBinding.
L’exemple suivant montre comment créer un KeyBinding entre un KeyGesture et un RoutedCommand.
<Window.InputBindings>
<KeyBinding Key="B"
Modifiers="Control"
Command="ApplicationCommands.Open" />
</Window.InputBindings>
KeyGesture OpenKeyGesture = new KeyGesture(
Key.B,
ModifierKeys.Control);
KeyBinding OpenCmdKeybinding = new KeyBinding(
ApplicationCommands.Open,
OpenKeyGesture);
this.InputBindings.Add(OpenCmdKeybinding);
Dim OpenKeyGesture As New KeyGesture(Key.B, ModifierKeys.Control)
Dim OpenCmdKeybinding As New KeyBinding(ApplicationCommands.Open, OpenKeyGesture)
Me.InputBindings.Add(OpenCmdKeybinding)
Une autre façon d’associer un InputGesture à un RoutedCommand est d’ajouter le InputGesture au InputGestureCollection sur le RoutedCommand.
L’exemple suivant montre comment ajouter un KeyGesture à InputGestureCollection de RoutedCommand.
KeyGesture OpenCmdKeyGesture = new KeyGesture(
Key.B,
ModifierKeys.Control);
ApplicationCommands.Open.InputGestures.Add(OpenCmdKeyGesture);
Dim OpenCmdKeyGesture As New KeyGesture(Key.B, ModifierKeys.Control)
ApplicationCommands.Open.InputGestures.Add(OpenCmdKeyGesture)
CommandBinding
Une CommandBinding commande associe une commande aux gestionnaires d’événements qui implémentent la commande.
La CommandBinding classe contient une Command propriété, et PreviewExecuted, , Executed, PreviewCanExecuteet CanExecute des événements.
Command est la commande à laquelle il CommandBinding est associé. Les gestionnaires d’événements qui sont attachés aux PreviewExecuted événements et Executed implémentent la logique de commande. Les gestionnaires d’événements attachés aux PreviewCanExecute événements et CanExecute déterminent si la commande peut s’exécuter sur la cible de commande actuelle.
L’exemple suivant montre comment créer un CommandBinding à la racine Window d’une application. Associe CommandBinding la commande Open avec les gestionnaires Executed et CanExecute.
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Open"
Executed="OpenCmdExecuted"
CanExecute="OpenCmdCanExecute"/>
</Window.CommandBindings>
// Creating CommandBinding and attaching an Executed and CanExecute handler
CommandBinding OpenCmdBinding = new CommandBinding(
ApplicationCommands.Open,
OpenCmdExecuted,
OpenCmdCanExecute);
this.CommandBindings.Add(OpenCmdBinding);
' Creating CommandBinding and attaching an Executed and CanExecute handler
Dim OpenCmdBinding As New CommandBinding(ApplicationCommands.Open, AddressOf OpenCmdExecuted, AddressOf OpenCmdCanExecute)
Me.CommandBindings.Add(OpenCmdBinding)
Ensuite, un ExecutedRoutedEventHandler et un CanExecuteRoutedEventHandler sont créés. Le ExecutedRoutedEventHandler ouvre un MessageBox qui affiche un message indiquant que la commande a été exécutée. Le CanExecuteRoutedEventHandler définit la propriété CanExecute à true
.
void OpenCmdExecuted(object target, ExecutedRoutedEventArgs e)
{
String command, targetobj;
command = ((RoutedCommand)e.Command).Name;
targetobj = ((FrameworkElement)target).Name;
MessageBox.Show("The " + command + " command has been invoked on target object " + targetobj);
}
Private Sub OpenCmdExecuted(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
Dim command, targetobj As String
command = CType(e.Command, RoutedCommand).Name
targetobj = CType(sender, FrameworkElement).Name
MessageBox.Show("The " + command + " command has been invoked on target object " + targetobj)
End Sub
void OpenCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
Private Sub OpenCmdCanExecute(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
e.CanExecute = True
End Sub
A CommandBinding est attaché à un objet spécifique, tel que la racine Window de l’application ou un contrôle. L'objet auquel CommandBinding est attaché définit l'étendue de la liaison. Par exemple, un CommandBinding rattaché à un ancêtre de la cible de commande peut être atteint par l’événement Executed, mais un CommandBinding rattaché à un descendant de la cible de commande ne peut pas être atteint. Il s'agit d'une conséquence directe de la manière dont un RoutedEvent se propage et forme des bulles depuis l'objet qui déclenche l'événement.
Dans certaines situations, le CommandBinding est attaché à la cible de commande elle-même, par exemple avec la classe TextBox et les commandes Cut, Copy, et Paste. Bien souvent, il est plus pratique d’attacher l’élément CommandBinding à un ancêtre de la cible de commande, comme le Window principal ou l’objet Application, en particulier si le même CommandBinding peut être utilisé pour plusieurs cibles de commande. Il s’agit de décisions de conception à prendre en compte lorsque vous créez votre infrastructure de commande.
Cible de commande
La cible de commande est l’élément sur lequel la commande est exécutée. En ce qui concerne un RoutedCommand, la cible de commande est l’élément où le routage de Executed et CanExecute débute. Comme indiqué précédemment, dans WPF, la propriété CommandTarget sur ICommandSource est seulement applicable lorsque ICommand est un RoutedCommand. Si le CommandTarget paramètre est défini sur un ICommandSource et que la commande correspondante n’est pas un RoutedCommand, la cible de commande est ignorée.
La source de commande peut définir explicitement la cible de commande. Si la cible de commande n’est pas définie, l’élément avec focus clavier est utilisé comme cible de commande. L’un des avantages de l’utilisation de l’élément avec le focus clavier comme cible de commande est qu’il permet au développeur d’applications d’utiliser la même source de commande pour appeler une commande sur plusieurs cibles sans avoir à suivre la cible de commande. Par exemple, si une MenuItem commande Paste est appelée dans une application disposant d’un TextBox contrôle et d’un PasswordBox contrôle, la cible peut être la TextBox ou PasswordBox selon le focus clavier du contrôle.
L’exemple suivant montre comment définir explicitement la cible de commande dans le balisage et dans le code-behind.
<StackPanel>
<Menu>
<MenuItem Command="ApplicationCommands.Paste"
CommandTarget="{Binding ElementName=mainTextBox}" />
</Menu>
<TextBox Name="mainTextBox"/>
</StackPanel>
// Creating the UI objects
StackPanel mainStackPanel = new StackPanel();
TextBox pasteTextBox = new TextBox();
Menu stackPanelMenu = new Menu();
MenuItem pasteMenuItem = new MenuItem();
// Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem);
mainStackPanel.Children.Add(stackPanelMenu);
mainStackPanel.Children.Add(pasteTextBox);
// Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste;
// Setting the command target to the TextBox
pasteMenuItem.CommandTarget = pasteTextBox;
' Creating the UI objects
Dim mainStackPanel As New StackPanel()
Dim pasteTextBox As New TextBox()
Dim stackPanelMenu As New Menu()
Dim pasteMenuItem As New MenuItem()
' Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem)
mainStackPanel.Children.Add(stackPanelMenu)
mainStackPanel.Children.Add(pasteTextBox)
' Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste
Le CommandManager
Le CommandManager assure un certain nombre de fonctions liées à la commande. Il fournit un ensemble de méthodes statiques permettant d’ajouter et de supprimer PreviewExecuted, Executed, PreviewCanExecuteet des gestionnaires d’événements vers et CanExecute à partir d’un élément spécifique. Il fournit un moyen d’inscrire les objets CommandBinding et InputBinding dans une classe spécifique. Le CommandManager fournit également un moyen, par le biais de l’événement RequerySuggested, d’avertir une commande quand elle doit lever l’événement CanExecuteChanged.
La méthode InvalidateRequerySuggested force CommandManager à déclencher l’événement RequerySuggested. Cela est utile pour les conditions qui doivent désactiver/activer une commande, mais ne sont pas des conditions dont la CommandManager connaissance est prise en compte.
Bibliothèque de commandes
WPF fournit un ensemble de commandes prédéfinies. La bibliothèque de commandes se compose des classes suivantes : ApplicationCommands, , NavigationCommandsMediaCommands, EditingCommands, et le ComponentCommands. Ces classes fournissent des commandes telles que Cut, BrowseBack et BrowseForward, Play, Stopet Pause.
La plupart de ces commandes incluent un ensemble de liaisons d’entrée par défaut. Par exemple, si vous spécifiez que votre application gère la commande de copie, vous obtenez automatiquement la liaison clavier « Ctrl+C » Vous obtenez également des liaisons pour d’autres périphériques d’entrée, tels que les mouvements de stylet tablet PC et les informations vocales.
Lorsque vous référencez des commandes dans les différentes bibliothèques de commandes à l’aide de XAML, vous pouvez généralement omettre le nom de classe de la classe de bibliothèque qui expose la propriété de commande statique. En règle générale, les noms de commandes ne sont pas ambigus en tant que chaînes et les types propriétaires existent pour fournir un regroupement logique de commandes, mais ne sont pas nécessaires pour la désambiguation. Par exemple, vous pouvez spécifier Command="Cut"
plutôt que le plus détaillé Command="ApplicationCommands.Cut"
. Il s’agit d’un mécanisme pratique intégré au processeur XAML WPF pour les commandes (plus précisément, il s’agit d’un comportement de convertisseur de type ICommand, auquel le processeur XAML WPF fait référence au moment du chargement).
Création de commandes personnalisées
Si les commandes des classes de bibliothèque de commandes ne répondent pas à vos besoins, vous pouvez créer vos propres commandes. Il existe deux façons de créer une commande personnalisée. La première consiste à commencer à partir de zéro et à implémenter l’interface ICommand. L’autre façon, et l’approche plus courante, consiste à créer un RoutedCommand ou un RoutedUICommand.
Pour obtenir un exemple de création d’un exemple personnalisé RoutedCommand, consultez Créer un exemple RoutedCommand personnalisé.
Voir aussi
.NET Desktop feedback