Przegląd Polecenia

Polecenia to mechanizm wejściowy w platformie Windows Presentation Foundation (WPF), który zapewnia obsługę danych wejściowych na poziomie bardziej semantyki niż dane wejściowe urządzenia. Przykłady poleceń to operacje kopiowania, wycinania i wklejania w wielu aplikacjach.

To omówienie definiuje, jakie polecenia znajdują się w WPF, które klasy są częścią modelu poleceń oraz jak używać i tworzyć polecenia w aplikacjach.

Ten temat zawiera następujące sekcje:

Co to są polecenia

Polecenia mają kilka celów. Pierwszym celem jest oddzielienie semantyki i obiektu, który wywołuje polecenie od logiki, która wykonuje polecenie. Dzięki temu wiele różnych źródeł może wywoływać tę samą logikę poleceń i umożliwia dostosowanie logiki poleceń do różnych elementów docelowych. Na przykład operacje edycji Kopiowanie, wycinanie i wklejanie, które znajdują się w wielu aplikacjach, mogą być wywoływane przy użyciu różnych akcji użytkownika, jeśli są implementowane przy użyciu poleceń. Aplikacja może zezwolić użytkownikowi na wycinanie zaznaczonych obiektów lub tekstu przez kliknięcie przycisku, wybranie elementu w menu lub użycie kombinacji klawiszy, takiej jak CTRL+X. Za pomocą poleceń można powiązać każdy typ akcji użytkownika z taką samą logiką.

Innym celem poleceń jest wskazanie, czy akcja jest dostępna. Aby kontynuować przykład wycinania obiektu lub tekstu, akcja ma sens tylko wtedy, gdy coś jest zaznaczone. Jeśli użytkownik spróbuje wytnij obiekt lub tekst bez niczego zaznaczonego, nic się nie stanie. Aby to wskazać użytkownikowi, wiele aplikacji wyłącza przyciski i elementy menu, aby użytkownik wiedział, czy można wykonać akcję. Polecenie może wskazać, czy akcja jest możliwa, implementując CanExecute metodę . Przycisk może subskrybować zdarzenie CanExecuteChanged i być wyłączony, CanExecute jeśli zwraca wartość lub false jest włączony, jeśli CanExecute zwraca wartość true.

Semantyka polecenia może być spójna w aplikacjach i klasach, ale logika akcji jest specyficzna dla konkretnego obiektu, na który działa. Kombinacja klawiszy CTRL +X wywołuje polecenie Wytnij w klasach tekstu, klasach obrazów i przeglądarkach internetowych, ale rzeczywista logika wykonywania operacji wycinania jest definiowana przez aplikację, która wykonuje wycinanie. Umożliwia RoutedCommand klientom implementowanie logiki. Obiekt tekstowy może wycinać zaznaczony tekst do schowka, a obiekt obrazu może wycinać wybrany obraz. Gdy aplikacja obsługuje zdarzenie Executed , ma dostęp do obiektu docelowego polecenia i może podjąć odpowiednie działania w zależności od typu obiektu docelowego.

Przykład prostego polecenia w WPF

Najprostszym sposobem użycia polecenia w WPF RoutedCommand jest użycie wstępnie zdefiniowanej z jednej z klas biblioteki poleceń; użycie kontrolki z natywną obsługą polecenia oraz użycie kontrolki, która ma natywną obsługę wywołania polecenia. To Paste polecenie jest jednym ze wstępnie zdefiniowanych poleceń w ApplicationCommands klasie . Kontrolka TextBox ma wbudowaną logikę do obsługi Paste polecenia. Klasa ma MenuItem natywną obsługę wywołania poleceń.

W poniższym przykładzie pokazano MenuItemPasteTextBox, jak skonfigurować obiekt tak, aby po jego kliknięciu było wywoływane polecenie na , przy założeniu, że obiekt ma TextBox fokus klawiatury.

<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

Cztery główne pojęcia związane z poleceniami WPF

Model poleceń trasowany w WPF można podzielić na cztery główne pojęcia: polecenie, źródło polecenia, element docelowy polecenia i powiązanie polecenia:

  • Polecenie to akcja do wykonania.

  • Źródło polecenia jest obiektem, który wywołuje polecenie.

  • Element docelowy polecenia jest obiektem, na który jest wykonywane polecenie.

  • Powiązanie polecenia jest obiektem, który mapuje logikę polecenia na polecenie .

W poprzednim przykładzie polecenie Paste to polecenie , MenuItem element to źródło polecenia, TextBox element to element docelowy polecenia, a powiązanie polecenia jest dostarczane przez kontrolkę TextBox . Warto zauważyć, że nie zawsze jest CommandBinding tak, że obiekt jest dostarczany przez kontrolkę, która jest klasą docelową polecenia. Często element musi CommandBinding zostać utworzony przez dewelopera aplikacji lub CommandBinding element może być dołączony do elementu nadrzędnego elementu docelowego polecenia.

Polecenia

Polecenia w WPF są tworzone przez zaimplementowanie interfejsu ICommand . ICommanduwidacznia dwie metodyExecute: , CanExecutei oraz zdarzenie . CanExecuteChanged Execute wykonuje akcje skojarzone z poleceniem . CanExecute Określa, czy polecenie można wykonać na bieżącego obiektu docelowego polecenia. CanExecuteChanged jest wywoływana, jeśli menedżer poleceń, który centralizuje operacje poleceń wykrywa zmianę w źródle polecenia, która może unieważnić polecenie, które zostało podniesione, ale nie zostało jeszcze wykonane przez powiązanie polecenia. Implementacja WPF jest ICommand klasą RoutedCommand i jest głównym tematem tego przeglądu.

Głównymi źródłami danych wejściowych w WPF są myszy, klawiatury, pisma odręcznego i kierowane polecenia. Im więcej danych wejściowych zorientowanych na urządzenie używa obiektu do RoutedEvent powiadamiania obiektów na stronie aplikacji o tym, że wystąpiło zdarzenie wejściowe. A RoutedCommand nie różni się. Metody Execute i CanExecuteRoutedCommand obiektu nie zawierają logiki aplikacji dla polecenia , ale zamiast tego podają kierowane zdarzenia, które tunelują i bąbelkują przez drzewo elementów, dopóki nie napotkają obiektu z elementem CommandBinding. Plik CommandBinding zawiera programy obsługi dla tych zdarzeń i to programy obsługi wykonują polecenie . Aby uzyskać więcej informacji na temat routingu zdarzeń w WPF, zobacz Routed Events Overview (Zdarzenia trasowane — omówienie).

Metoda Execute w metodzie zgłasza RoutedCommand zdarzenia PreviewExecuted i Executed na docelowym poleceniu. Metoda CanExecute w metodzie zgłasza RoutedCommand zdarzenia CanExecute i PreviewCanExecute na docelowym poleceniu. Te zdarzenia tunelują i bąbelkują przez drzewo elementów, dopóki nie napotkają obiektu, który ma dla CommandBinding tego określonego polecenia.

WPF dostarcza zestaw typowych poleceń trasowane rozrzutu w kilku klasach: MediaCommands, ApplicationCommands, NavigationCommands, ComponentCommandsi EditingCommands. Te klasy składają się tylko z obiektów RoutedCommand , a nie logiki implementacji polecenia. Logika implementacji jest odpowiedzialna za obiekt, na którym jest wykonywane polecenie.

Źródła poleceń

Źródło polecenia jest obiektem, który wywołuje polecenie. Przykłady źródeł poleceń to MenuItem, Buttoni KeyGesture.

Źródła poleceń w WPF zwykle implementują ICommandSource interfejs .

ICommandSource Udostępnia trzy właściwości: Command, CommandTargeti CommandParameter:

  • Command to polecenie do wykonania po wywołaniu źródła polecenia.

  • CommandTarget to obiekt, na którym ma być wykonane polecenie . Warto zauważyć, że w WPF CommandTarget właściwość w ICommandSource obiekcie ma zastosowanie tylko wtedy, gdy obiekt ICommand ma wartość RoutedCommand. Jeśli jest CommandTarget ustawiona na i ICommandSource odpowiednie polecenie nie jest , RoutedCommandobiekt docelowy polecenia jest ignorowany. Jeśli nie CommandTarget jest ustawiona, element z fokusem klawiatury będzie obiektem docelowym polecenia.

  • CommandParameter to zdefiniowany przez użytkownika typ danych używany do przekazania informacji do programów obsługi implementjących polecenie .

Klasy WPF implementują klasy ICommandSourceButtonBase, MenuItem, Hyperlinki InputBinding. ButtonBase, MenuItemi wywołują Hyperlink polecenie po ich kliknięciu, a InputBinding polecenie wywołuje polecenie po wykonaniu InputGesture skojarzonego z nim polecenia.

W poniższym przykładzie pokazano, jak używać typu MenuItem w ContextMenu pliku jako źródła polecenia dla Properties polecenia .

<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

Zazwyczaj źródło polecenia nasłuchuje CanExecuteChanged zdarzenia. To zdarzenie informuje źródło polecenia, że możliwość wykonania polecenia w bieżącym celu polecenia może ulec zmianie. Źródło polecenia może odpytywać bieżący stan przy RoutedCommand użyciu CanExecute metody . Źródło polecenia może następnie wyłączyć się, jeśli nie można wykonać polecenia. Przykładem jest wyszarzenie MenuItem się, gdy nie można wykonać polecenia.

Element InputGesture może służyć jako źródło polecenia. Dwa typy gestów wejściowych w WPF to i KeyGestureMouseGesture. Możesz myśleć o skrótie KeyGesture klawiaturowym, takim jak CTRL+C. Obiekt KeyGesture składa się z zestawu Key i ModifierKeys. Element MouseGesture składa się z i MouseAction opcjonalnego zestawu .ModifierKeys

Aby element działał InputGesture jako źródło polecenia, musi być skojarzony z poleceniem. Istnieje kilka sposobów osiągnięcia tego celu. Jednym ze sposobów jest użycie .InputBinding

W poniższym przykładzie pokazano, jak utworzyć argument między KeyBinding a KeyGesture i 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)

Innym sposobem skojarzenia InputGesture z elementem RoutedCommand jest dodanie InputGestureInputGestureCollectionRoutedCommanddo .

W poniższym przykładzie pokazano, jak dodać do KeyGesture tabeli InputGestureCollection .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

CommandBinding Skojarz polecenie z programami obsługi zdarzeń, które implementują polecenie.

Klasa CommandBinding zawiera właściwość oraz Command zdarzenia PreviewExecuted, Executed, PreviewCanExecutei CanExecute .

Command to polecenie, z które CommandBinding jest kojarzona. Procedury obsługi zdarzeń, które są dołączone do zdarzeń PreviewExecuted i implementują Executed logikę polecenia. Procedury obsługi zdarzeń dołączone do PreviewCanExecute zdarzenia i CanExecute określają, czy polecenie może zostać wykonane na bieżącym celu polecenia.

W poniższym przykładzie pokazano, jak utworzyć element CommandBinding w Window katalogu głównym aplikacji. CommandBinding Skojarz polecenie Open z programami Executed obsługi CanExecute i .

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

Następnie tworzone są ExecutedRoutedEventHandler i CanExecuteRoutedEventHandler . Otwiera ExecutedRoutedEventHandler , który MessageBox wyświetla ciąg z informacją, że polecenie zostało wykonane. Właściwość CanExecuteRoutedEventHandler jest ustawiana CanExecute na wartość 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

Obiekt CommandBinding jest dołączany do określonego obiektu, takiego jak katalog Window główny aplikacji lub kontrolka. Obiekt, do który CommandBinding jest dołączony, definiuje zakres powiązania. Na przykład element dołączony CommandBinding do elementu Executed nadrzędnego elementu docelowego polecenia może zostać osiągnięty przez zdarzenie, CommandBinding ale nie można uzyskać dostępu do elementu potomnego obiektu docelowego polecenia. Jest to bezpośrednia konsekwencja sposobu tunelowania i RoutedEvent bąbelków z obiektu, który wywołuje zdarzenie.

W niektórych sytuacjach obiekt jest CommandBinding dołączony do samego obiektu docelowego polecenia, TextBoxCutna przykład za pomocą klasy i poleceń , Copyi Paste . Jednak dość CommandBinding często wygodniej jest dołączyć element do elementu nadrzędnego elementu docelowego polecenia, takiego jak main Window lub obiekt Application, CommandBinding zwłaszcza jeśli ten sam element może być używany dla wielu elementów docelowych poleceń. Są to decyzje projektowe, które należy wziąć pod uwagę podczas tworzenia infrastruktury poleceń.

Element docelowy polecenia

Element docelowy polecenia jest elementem, na którym jest wykonywane polecenie. W odniesieniu do , RoutedCommandelement docelowy polecenia jest elementem, w którym uruchamia routing Executed i CanExecute . Jak wspomniano wcześniej, w WPF właściwość CommandTarget na ICommandSource ma zastosowanie tylko wtedy, gdy jest ICommand .RoutedCommand Jeśli obiekt CommandTarget jest ustawiony na i ICommandSource odpowiednie polecenie nie jest obiektem RoutedCommanddocelowym polecenia jest ignorowany.

Źródło polecenia może jawnie ustawić element docelowy polecenia. Jeśli element docelowy polecenia nie jest zdefiniowany, element z fokusem klawiatury będzie używany jako element docelowy polecenia. Jedną z zalet używania elementu z fokusem klawiatury jako elementu docelowego polecenia jest to, że umożliwia deweloperowi aplikacji używanie tego samego źródła polecenia do wywoływania polecenia na wielu elementach docelowych bez konieczności śledzenia elementu docelowego polecenia. Jeśli na przykład element wywołuje MenuItem polecenie WklejTextBoxPasswordBox w aplikacji, która ma kontrolkę i kontrolkę, obiektem docelowym może być element lub w zależności od tego, TextBoxPasswordBox która kontrolka ma fokus klawiatury.

W poniższym przykładzie pokazano, jak jawnie ustawić element docelowy polecenia w znacznikach i w kodzie za.

<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

The CommandManager

Polecenie CommandManager obsługuje wiele funkcji związanych z poleceniami. Udostępnia zestaw metod statycznych do dodawania PreviewExecutedi usuwania programów obsługi zdarzeń , Executed, PreviewCanExecutei CanExecute do i z określonego elementu. Zapewnia ona sposób rejestrowania obiektów CommandBinding i InputBinding w określonej klasie. Zapewnia CommandManager również sposób, za pośrednictwem RequerySuggested zdarzenia, aby powiadomić polecenie, gdy powinno zgłosić CanExecuteChanged zdarzenie.

Metoda InvalidateRequerySuggested wymusza, aby CommandManager zgłaszać RequerySuggested zdarzenie. Jest to przydatne w przypadku warunków, które powinny wyłączać/włączać polecenie, ale nie są to warunki, o CommandManager których użytkownik wie.

Biblioteka poleceń

WPF udostępnia zestaw wstępnie zdefiniowanych poleceń. Biblioteka poleceń składa się z następujących klas: ApplicationCommands, NavigationCommands, MediaCommands, EditingCommandsi ComponentCommands. Te klasy zawierają polecenia, takie Cutjak , BrowseBack i BrowseForward, Play, Stopi Pause.

Wiele z tych poleceń zawiera zestaw domyślnych powiązań wejściowych. Jeśli na przykład określisz, że aplikacja obsługuje polecenie kopiowania, automatycznie otrzymasz powiązanie klawiatury "CTRL+C". Otrzymasz również powiązania dla innych urządzeń wejściowych, takich jak gesty piórem tabletu i informacje o mowie.

Odwołania do poleceń w różnych bibliotekach poleceń przy użyciu odwołań procesora XAML WPF WPF w czasie ładowania).

Tworzenie Polecenia niestandardowe

Jeśli polecenia w klasach biblioteki poleceń nie spełniają Twoich potrzeb, możesz tworzyć własne polecenia. Istnieją dwa sposoby tworzenia polecenia niestandardowego. Pierwszy to rozpoczęcie od podstaw i zaimplementowanie ICommand interfejsu. Innym sposobem i bardziej powszechnym podejściem jest utworzenie metody lub RoutedCommandRoutedUICommand.

Aby uzyskać przykład tworzenia niestandardowego interfejsu RoutedCommand, zobacz Create a Custom RoutedCommand Sample (Tworzenie niestandardowego routed przykładu).

Zobacz też