TOC

This article is currently in the process of being translated into Dutch (~97% done).

Commands:

Using WPF commands

In het vorige artikel bespraken we veel theorie over wat commando's zijn en hoe ze werken. In dit hoofdstuk zullen we onderzoeken hoe u opdrachten daadwerkelijk gebruikt, door ze toe te wijzen aan elementen in de gebruiker interface en opdracht bindingen te maken die alles met elkaar verbinden.

We beginnen met een heel eenvoudig voorbeeld:

<Window x:Class="WpfTutorialSamples.Commands.UsingCommandsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="UsingCommandsSample" Height="100" Width="200">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.New" Executed="NewCommand_Executed" CanExecute="NewCommand_CanExecute" />
    </Window.CommandBindings>

    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Command="ApplicationCommands.New">New</Button>
    </StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace WpfTutorialSamples.Commands
{
	public partial class UsingCommandsSample : Window
	{
		public UsingCommandsSample()
		{
			InitializeComponent();
		}

		private void NewCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}

		private void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			MessageBox.Show("The New command was invoked");
		}
	}
}

We definiëren een opdracht binding voor het venster door het aan zijn verzameling CommandBindings toe te voegen. We specificeren het commando dat we willen gebruiken (het commando New van de ApplicationCommands), evenals twee gebeurtenissen. De visuele interface bestaat uit een enkele knop, waarmee we de opdracht koppelen aan het gebruik van de eigenschap Command.

In de achterliggende code behandelen we de twee evenementen. De CanExecute afwikkeling, die WPF zal gebruiken als de toepassing niet actief is om te zien of de specifieke opdracht momenteel beschikbaar is - in dit voorbeeld zeer eenvoudig - omdat we willen dat deze specifieke opdracht altijd beschikbaar is. Dit wordt gedaan door de eigenschap CanExecutevan de gebeurtenis argumenten in te stellen op true.

De Executed afwikkeling toont eenvoudigweg een berichtvenster wanneer de opdracht wordt opgeroepen. Als u het voorbeeld uitvoert en op de knop drukt, ziet u dit bericht. Een ding om op te letten is dat dit commando een standaard sneltoets gedefinieerd heeft, die je krijgt als een toegevoegde bonus. In plaats van op de knop te klikken, kunt u proberen Ctrl + N op uw toetsenbord in te drukken - het resultaat is hetzelfde.

Gebruik de CanExecute methode

In het eerste voorbeeld hebben we een CanExecute gebeurtenis geïmplementeerd die eenvoudig true retourneerde, zodat de knop altijd beschikbaar was. Dit is natuurlijk niet het geval voor alle knoppen - in veel gevallen wilt u dat de knop ingeschakeld of uitgeschakeld wordt, afhankelijk van een of andere status in uw toepassing.

Een heel gebruikelijk voorbeeld hiervan is het omschakelen van knoppen voor het gebruik van het Windows Klembord, waar u de Knippen en Kopiëren-knoppen alleen wilt inschakelen wanneer tekst is geselecteerd, en de Knop Plakken om alleen te worden ingeschakeld wanneer er tekst aanwezig is op het klembord. Dit is precies wat we in dit voorbeeld zullen bereiken:

<Window x:Class="WpfTutorialSamples.Commands.CommandCanExecuteSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CommandCanExecuteSample" Height="200" Width="250">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Cut" CanExecute="CutCommand_CanExecute" Executed="CutCommand_Executed" />
        <CommandBinding Command="ApplicationCommands.Paste" CanExecute="PasteCommand_CanExecute" Executed="PasteCommand_Executed" />
    </Window.CommandBindings>
    <DockPanel>
        <WrapPanel DockPanel.Dock="Top" Margin="3">
            <Button Command="ApplicationCommands.Cut" Width="60">_Cut</Button>
            <Button Command="ApplicationCommands.Paste" Width="60" Margin="3,0">_Paste</Button>
        </WrapPanel>
        <TextBox AcceptsReturn="True" Name="txtEditor" />
    </DockPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace WpfTutorialSamples.Commands
{
	public partial class CommandCanExecuteSample : Window
	{
		public CommandCanExecuteSample()
		{
			InitializeComponent();
		}

		private void CutCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = (txtEditor != null) && (txtEditor.SelectionLength > 0);
		}

		private void CutCommand_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			txtEditor.Cut();
		}

		private void PasteCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = Clipboard.ContainsText();
		}

		private void PasteCommand_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			txtEditor.Paste();
		}
	}
}

We hebben dus deze heel eenvoudige interface met een paar knoppen en een TextBox element. De eerste knop plaatst tekst naar het klembord en de tweede verwijderd het er af.

In de achterliggende code hebben we twee gebeurtenissen voor elke knop: één die de daadwerkelijke actie uitvoert, welke naam eindigt op _Executed en vervolgens de CanExecute gebeurtenissen. In elk daarvan ziet u dat ik een beetje logica toepas om te beslissen of de actie kan worden uitgevoerd en om deze vervolgens toewijzen aan de retourwaarde CanExecute met de EventArgs.

Het leuke hiervan is dat je deze methoden niet hoeft te gebruiken om je knoppen te laten updaten - WPF doet het automatisch wanneer de applicatie een rustmoment heeft, en zorgt ervoor dat je interface de hele tijd up-to-date blijft.

Standaard commando gedrag en CommandTarget

Zoals we in het vorige voorbeeld hebben gezien, kan het verwerken van een reeks opdrachten nogal wat code opleveren, met veel methode verklaringen en logica. Dat is waarschijnlijk de reden waarom het WPF team heeft besloten om het voor je af te handelen. In feite hadden we alle achter liggende code in het vorige voorbeeld kunnen vermijden, omdat een WPF TextBox automatisch gemeenschappelijke commando's zoals Knippen, Kopiëren, Plakken, Ongedaan maken en Opnieuw kan verwerken.

WPF doet dit door de Executed- en CanExecute-gebeurtenissen voor u af te handelen, wanneer een tekstinvoer element zoals de TextBox focus heeft. U bent vrij om deze gebeurtenissen te negeren, wat in feite is wat we in het vorige voorbeeld hebben gedaan, maar als u alleen het basisgedrag wilt, kunt u WPF de opdrachten en de TextBox besturing laten verbinden en het werk voor u doen. Kijk eens hoe veel eenvoudiger dit voorbeeld is:

<Window x:Class="WpfTutorialSamples.Commands.CommandsWithCommandTargetSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CommandsWithCommandTargetSample" Height="200" Width="250">
    <DockPanel>
        <WrapPanel DockPanel.Dock="Top" Margin="3">
            <Button Command="ApplicationCommands.Cut" CommandTarget="{Binding ElementName=txtEditor}" Width="60">_Cut</Button>
            <Button Command="ApplicationCommands.Paste" CommandTarget="{Binding ElementName=txtEditor}" Width="60" Margin="3,0">_Paste</Button>
        </WrapPanel>
        <TextBox AcceptsReturn="True" Name="txtEditor" />
    </DockPanel>
</Window>

Geen achter liggende code nodig voor dit voorbeeld - WPF behandelt dit allemaal voor ons, maar alleen omdat we deze specifieke commando's voor dit specifieke element willen gebruiken. De TextBox doet het werk voor ons.

Merk op hoe ik de eigenschappen van CommandTarget op de knoppen gebruik om de opdrachten aan onze TextBox besturing te binden. Dit is in dit specifieke voorbeeld vereist, omdat het WrapPanel de focus niet op dezelfde manier verwerkt, bijvoorbeeld een werkbalk of een menu zou het doen, maar het is ook redelijk goed om de commando's een doel te geven.

Samenvatting

Het omgaan met commando's is best rechttoe rechtaan, maar het gaat wel om een beetje extra opmaak en code. De beloning is vooral duidelijk wanneer u dezelfde actie vanuit meerdere plaatsen moet aanroepen, of wanneer u ingebouwde opdrachten gebruikt die WPF volledig voor u aankan, zoals we in het vorige voorbeeld zagen.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!