TOC

This article has been localized into Danish by the community.

Kommandoer:

Brug af WPF kommandoer

I sidste artikel diskuterede vi en masse teori om hvad, kommandoer er, og hvordan de virker. I dette afsnit vil vi se på hvordan, du faktisk bruger kommandoer ved at tildele dem til elementer i brugerinterfacet og oprette kommandobindinger, som kæder det hele sammen.

Vi starter med et meget simpelt eksempel:

<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");
		}
	}
}

Vi definerer en kommandobinding på Window ved at tilføje den til dets CommandBinding samling. Vi angiver den kommando, vi vil bruge (New kommandoen fra ApplicationCommands) sammen med to event handlere. Det visuelle interface består af en enkelt knap, som vi knytter til kommandoen ved hjælp af Commans egenskaben.

I code-behind håndterer vi de to hænselser. CanExecute handleren, som WPF vil kalde, når applikationen er ledig for at se, om den specifikke kommando er tilgængelig lige nu, er meget simple i dette eksempel, da vi ønsker, at denne kommand altid er tilgængelig. Dette gøres ved at sætte CanExecute egenskaben i hændelsesparameteren til true.

Executed handleren viser blot en meddelelsesboks, når kommandoen bliver kaldt. Hvis du kører eksemplet og trykker på knappen, vil du se denne besked. En ting at bemærke er, at kommandoen har en standard tastaturgenvej defineret, hvilket du får som en bonus. I stedet for at klikke på knappen, kan du prøe at trykke Ctrl+N på tastaturet - resultatet er det samme.

Brug af CanExecute metoden

I det første eksempel implementerede vi en CanExecute hændelse, som blot returnerede true, så knappen altid er tilgængelig. Men dette er naturligvis ikke sandt for alle knapper - i mange tilfælde ønsker du knappen skal være aktiveret eller deaktiveret afhængig af en eller anden status i din applikation.

Et meget almindeligt eksempel på dette er skiftet af knapper til at bruge Windows Udklipsholder, hvor du ønsker, at Cut og Copy knapperne kun skal være aktiveret, når der er markeret tekst, og Paste knappen kun skal være aktiveret, når der er tekst i udklipsholderen. Dette er nøjagtig hvad, vi opnår i dette eksempel:

<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();
		}
	}
}

Så, her har vi et simpelt interface med et par knapper og en TextBox kontrol. Den første knap vil klippe til udklipsholderen, og den anden vil sætte ind fra udklipsholderen.

I code-behind har vi to hændelser for hver knap: En, som udføre handlingen, med navnet sluttende med _Executed, og så CanExecute hændelsen. I hver af dem vil du se, at jeg laver noget logik for at afgøre, om handlingen kan udføres eller ej og derefter tildeler resultatet til returnværdien CanEcexute på EventArgs parameteren.

Det fed med dette er, at du ikke er nødt til at kalde disse metoder for at have dine knapper opdateret. WPF gør dette automatisk, når din applikation har en ledig stund for at sørge for, at dit interface er opdateret hele tiden.

Standard kommandoopførsel og CommandTarget

Som vi så i det forrige eksempel, kan håndtering af et sæt kommandoer føre til en del kode, med en stor del værende metodeerklæringer og meget standardlogik. Dette er sikker grunden til, at WPF-holdet besluttede at håndtere noget af det for dig. Faktusk kunne vi have undgået al code-behind i det forrige eksempel, fordi en WPF TextBox automatisk kan håndtere almindelige kommandoer som Cut, Copy, Paste, Undo og Redo.

WPF gør dette ved at håndtere Executed og CanExecute hændelserne for dig, når en tekstindtastningskontrol som TextBox har fokus. Du kan frit overstyre disse hændelser, hvilket er hvad, vi gjorde i det forrige sksempel, men hvis du bare ønsker den grundlæggende opførsel, kan du lave WPF forbinde kommandoerne og TextBox kontrollen og gøre arbejdet for dig. Bare se hvor meget simplere, dette eksempel er:

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

Ingen code-behind kode behøves til dette eksempel - WPF håndterer det hele for os, men kun fordi vi ønsker at bruge disse specifikke kommandoer til denne specifikke kontrol. TextBox kontrollen gør arbejdet for os.

Bemærk hvordan, jeg bruger CommandTarget egenskaben på kanpperne til at binde kommandoerne til vores TextBox kontrol. Dette er krævet i dette eksempel, da WrapPanel ikke håndterer fokus på samme måde, som en Toolbar eller en Menu ville gøre, men det giver også mening at kommandoerne et mål.

Resume

At arbejde med kommandoer er ret ligetil, men kræver en smule ekstra markup og kode. Belønningen er dog specielt tydelig, når du har brug for at udføre den samme handling fra flere steder, eller når du bruger indbyggede kommandoer, som WPF kan håndtere fuldstændig for dig, som vi så i det sidste eksempel.


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!