Przegląd Polecenia

Polecenie jest mechanizmem wprowadzania, w Windows Presentation Foundation (WPF) którym zapewnia obsługę wejścia na wyższym poziomie semantycznym niż dane wejściowe urządzenia. Przykładami poleceń są operacje kopiowania, wycinania i wklejania w wielu aplikacjach.

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

Ten temat zawiera następujące sekcje:

Co to są polecenia

Polecenia mają kilka zastosowań. Pierwszy cel polega na rozdzieleniu semantyki i obiektu, który wywołuje polecenie z logiki, która wykonuje polecenie. Pozwala to na wiele i różne źródła do wywołania tej samej logiki poleceń i umożliwia dostosowanie logiki poleceń dla 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 za pomocą poleceń. Aplikacja może zezwolić użytkownikowi na wycinanie wybranych 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ć poszczególne typy akcji użytkownika z tą 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 próbuje wyciąć obiekt lub tekst bez żadnych wybranych elementów, nic się nie stało. Aby wskazać to użytkownikowi, wiele aplikacji wyłącza przyciski i elementy menu, dzięki czemu użytkownik wie, czy można wykonać akcję. Polecenie może wskazywać, czy możliwe jest wykonanie akcji przez implementację CanExecute metody. Przycisk może subskrybować CanExecuteChanged zdarzenie i zostać wyłączony, jeśli CanExecute zwraca false lub zostanie 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. Kombinacja klawiszy CTRL + X wywołuje polecenie Wytnij w klasach tekstowych, klasach obrazów i przeglądarkach sieci Web, ale rzeczywista logika wykonywania operacji wycinania jest definiowana przez aplikację wykonującą wycinanie. A RoutedCommand umożliwia klientom implementację logiki. Obiekt tekstowy może wyciąć zaznaczony tekst do schowka, podczas gdy obiekt obrazu może wyciąć wybrany obraz. Gdy aplikacja obsługuje Executed zdarzenie, ma dostęp do obiektu docelowego polecenia i może podejmować odpowiednie działania w zależności od typu elementu docelowego.

Proste przykładowe polecenie w WPF

Najprostszym sposobem użycia polecenia w programie WPF jest użycie wstępnie zdefiniowanego RoutedCommand z jednej z klas bibliotek poleceń; Użyj formantu, który ma natywną obsługę obsługi polecenia; i użyj formantu, który ma natywną obsługę wywoływania polecenia. PastePolecenie jest jednym ze wstępnie zdefiniowanych poleceń w ApplicationCommands klasie. TextBoxFormant ma wbudowaną logikę do obsługi Paste polecenia. I MenuItem Klasa ma natywną obsługę Wywoływanie poleceń.

Poniższy przykład pokazuje, jak skonfigurować program, MenuItem Aby po jego kliknięciu wywoła Paste polecenie na TextBox , przy założeniu, że TextBox ma 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 koncepcje w przypadku poleceń WPF

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

  • Polecenie jest akcją do wykonania.

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

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

  • Powiązanie polecenia to obiekt, który mapuje logikę poleceń na polecenie.

W poprzednim przykładzie Paste polecenie jest poleceniem, MenuItem jest źródłem polecenia, TextBox jest elementem docelowym polecenia i powiązanie polecenia jest dostarczane przez TextBox formant. Należy zauważyć, że nie zawsze jest to przypadek, który CommandBinding jest dostarczany przez formant, który jest klasą docelową polecenia. Bardzo często CommandBinding musi być utworzony przez dewelopera aplikacji lub CommandBinding może być dołączony do obiektu nadrzędnego polecenia.

Polecenia

Polecenia w programie WPF są tworzone przez implementację ICommand interfejsu. ICommand uwidacznia dwie metody, Execute , i CanExecute i zdarzenie CanExecuteChanged . Execute wykonuje akcje, które są skojarzone z poleceniem. CanExecute Określa, czy polecenie można wykonać na bieżącym obiekcie docelowym polecenia. CanExecuteChanged jest zgłaszany, jeśli Menedżer poleceń, który służy do scentralizowania operacji wykonywania poleceń, wykrywa zmiany w źródle poleceń, które mogą unieważnić polecenie, które zostało podniesione, ale nie zostało jeszcze wykonane przez powiązanie polecenia. WPFImplementacja ICommand jest RoutedCommand klasą i jest fokusem tego omówienia.

Główne źródła danych wejściowych w programie WPF to mysz, klawiatura, atrament i rozesłane polecenia. Dodatkowe dane wejściowe zorientowane na urządzenia używają RoutedEvent do powiadamiania obiektów na stronie aplikacji o wystąpieniu zdarzenia wejściowego. A RoutedCommand nie różni się. ExecuteMetody i nie CanExecute RoutedCommand zawierają logiki aplikacji dla polecenia, ale raczej zgłaszają zdarzenia kierowane, które tuneluje i bąbelki przez drzewo elementów do momentu wystąpienia obiektu z CommandBinding . CommandBindingZawiera programy obsługi tych zdarzeń i jest obsługą, która wykonuje polecenie. Aby uzyskać więcej informacji na temat routingu zdarzeń w programie WPF , zobacz Omówienie zdarzeń kierowanych.

ExecuteMetoda RoutedCommand PreviewExecuted obiektu wywołuje i Executed zdarzenia w celu polecenia. CanExecuteMetoda na RoutedCommand wywołuje CanExecute PreviewCanExecute zdarzenia i w obiekcie docelowym polecenia. Te zdarzenia są tunele i bąbelki przez drzewo elementów, dopóki nie napotkają obiektu CommandBinding , który ma dla danego polecenia.

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

Źródła poleceń

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

Źródła poleceń WPF ogólnie implementują ICommandSource interfejs.

ICommandSource uwidacznia trzy właściwości: Command , CommandTarget i CommandParameter :

  • Command jest poleceniem do wykonania, gdy zostanie wywołane źródło polecenia.

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

  • CommandParameter jest typem danych zdefiniowanym przez użytkownika, który służy do przekazywania informacji do programów obsługi implementujących polecenie.

WPFKlasy, które implementują ICommandSource to,, ButtonBase MenuItem Hyperlink , i InputBinding . ButtonBase, MenuItem i Hyperlink Wywołaj polecenie po kliknięciu i InputBinding wywołuje polecenie, gdy InputGesture jest wykonywane skojarzone z nim.

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

<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 będzie nasłuchiwać CanExecuteChanged zdarzenia. To zdarzenie informuje źródło polecenia, że możliwość wykonania polecenia w bieżącym obiekcie docelowym polecenia mogła ulec zmianie. Źródło polecenia może wysyłać zapytania do bieżącego stanu przy RoutedCommand użyciu CanExecute metody. Źródło polecenia może następnie wyłączyć, jeśli polecenie nie może zostać wykonane. Przykładem jest MenuItem szare wyjście, gdy polecenie nie może zostać wykonane.

InputGestureMoże służyć jako źródło polecenia. Dwa typy gestów wejścia w WPF to KeyGesture i MouseGesture . Można traktować KeyGesture jako skrót klawiaturowy, taki jak Ctrl + C. A KeyGesture składa się z Key i zestawu ModifierKeys . A MouseGesture składa się z MouseAction i opcjonalnego zestawu ModifierKeys .

InputGestureAby obiekt działał jako źródło polecenia, musi być skojarzony z poleceniem. Istnieje kilka sposobów, aby to zrobić. Jednym ze sposobów jest użycie InputBinding .

Poniższy przykład pokazuje, jak utworzyć KeyBinding między KeyGesture a 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 elementu InputGesture a RoutedCommand jest dodanie InputGesture do elementu InputGestureCollection w RoutedCommand .

Poniższy przykład pokazuje, jak dodać a KeyGesture do 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

A CommandBinding kojarzy polecenie z obsługą zdarzeń implementującą polecenie.

CommandBindingKlasa zawiera Command Właściwość, i,, PreviewExecuted Executed PreviewCanExecute i CanExecute zdarzenia.

Command jest poleceniem, CommandBinding z którym jest skojarzony. Programy obsługi zdarzeń dołączone do PreviewExecuted Executed zdarzeń i implementują logikę poleceń. Programy obsługi zdarzeń dołączone do PreviewCanExecute CanExecute zdarzeń i określają, czy polecenie można wykonać na bieżącym obiekcie docelowym polecenia.

Poniższy przykład pokazuje, jak utworzyć element CommandBinding w katalogu głównym Window aplikacji. CommandBindingKojarzy Open polecenie z Executed programami i 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)

Następnie ExecutedRoutedEventHandler CanExecuteRoutedEventHandler tworzone są i. ExecutedRoutedEventHandlerOtwiera a zostanie MessageBox wyświetlony ciąg informujący, że polecenie zostało wykonane. CanExecuteRoutedEventHandlerUstawia CanExecute Właściwość na 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 jest dołączony do określonego obiektu, takiego jak katalog główny Window aplikacji lub formantu. Obiekt, do którego CommandBinding jest dołączony, definiuje zakres powiązania. Na przykład, CommandBinding dołączone do elementu nadrzędnego elementu docelowego polecenia można osiągnąć przez Executed zdarzenie, ale CommandBinding nie można osiągnąć dołączonego elementu podrzędnego obiektu docelowego polecenia. Jest to bezpośrednia konsekwencja sposobu, w jaki RoutedEvent tunele i bąbelki z obiektu, który wywołuje zdarzenie.

W niektórych sytuacjach CommandBinding jest dołączony do samego obiektu docelowego polecenia, na przykład z TextBox klasą i Cut Copy Paste poleceniami, i. Dość często zdarza się, aby dołączyć CommandBinding do elementu nadrzędnego polecenia, takiego jak główny Window lub obiekt aplikacji, zwłaszcza jeśli CommandBinding można użyć tego samego polecenia dla wielu obiektów docelowych poleceń. Są to decyzje projektowe, które należy wziąć pod uwagę podczas tworzenia infrastruktury poleceń.

Element docelowy polecenia

Obiekt docelowy polecenia jest elementem, w którym polecenie jest wykonywane. W odniesieniu do RoutedCommand , obiekt docelowy polecenia jest elementem, w którym Routing Executed i CanExecute rozpoczyna się. Jak wspomniano wcześniej, WPF we CommandTarget Właściwości on ICommandSource ma zastosowanie tylko wtedy, gdy ICommand jest RoutedCommand . Jeśli CommandTarget jest ustawiona dla ICommandSource i odpowiednie polecenie nie jest RoutedCommand , obiekt docelowy polecenia jest ignorowany.

Źródło polecenia może jawnie ustawić element docelowy polecenia. Jeśli obiekt docelowy polecenia nie jest zdefiniowany, element z fokusem klawiatury będzie używany jako obiekt docelowy polecenia. Jedną z korzyści wynikających z używania elementu z fokusem klawiatury jako obiektu docelowego polecenia jest umożliwienie deweloperowi aplikacji używania tego samego źródła poleceń do wywołania polecenia na wielu celach, bez konieczności śledzenia obiektu docelowego polecenia. Na przykład jeśli MenuItem wywołuje polecenie wklejenia w aplikacji, która ma TextBox kontrolkę i PasswordBox kontrolkę, obiektem docelowym może być albo w TextBox zależności od tego, PasswordBox który formant ma fokus klawiatury.

Poniższy przykład pokazuje, jak jawnie ustawić obiekt docelowy polecenia w znacznikach i w kodzie.

<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

Polecenie CommandManager

Wykonuje CommandManager wiele funkcji związanych z poleceniem. Zawiera zestaw metod statycznych do dodawania i usuwania PreviewExecuted Executed PreviewCanExecute CanExecute programów obsługi zdarzeń oraz do i z określonego elementu. Umożliwia ona rejestrowanie CommandBinding i InputBinding obiekty w określonej klasie. CommandManagerUdostępnia również środki, RequerySuggested aby powiadomić polecenie o zdarzeniu CanExecuteChanged .

InvalidateRequerySuggestedMetoda wymusza wygenerowanie CommandManager RequerySuggested zdarzenia. Jest to przydatne w przypadku warunków, które powinny wyłączać/włączać polecenie, ale nie są to warunki, o których należy CommandManager wiedzieć.

Biblioteka poleceń

WPF udostępnia zestaw wstępnie zdefiniowanych poleceń. Biblioteka poleceń składa się z następujących klas: ApplicationCommands , NavigationCommands , MediaCommands , EditingCommands i ComponentCommands . Klasy te udostępniają polecenia, takie jak Cut , BrowseBack i BrowseForward ,, Play Stop i Pause .

Wiele z tych poleceń zawiera zestaw domyślnych powiązań wejściowych. Na przykład jeśli określisz, że aplikacja obsługuje polecenie copy, automatycznie otrzymujesz powiązanie klawiatury "CTRL + C", uzyskasz także powiązania z innymi urządzeniami wejściowymi, takimi jak gesty pióra komputera typu tablet i informacje o mowy.

Podczas odwoływania się do poleceń w różnych bibliotekach poleceń przy użyciu XAML , można zwykle pominąć nazwę klasy klasy biblioteki, która uwidacznia właściwość polecenia statycznego. Ogólnie rzecz biorąc, nazwy poleceń są niejednoznaczne jako ciągi i istnieją typy posiadające do zapewnienia logicznego grupowania poleceń, ale nie są niezbędne do uściślania. Na przykład można określić, Command="Cut" a nie pełne Command="ApplicationCommands.Cut" . Jest to wygodny mechanizm, który jest wbudowany w WPF XAML procesor dla poleceń (dokładniej, jest to zachowanie konwertera typów, które jest używane ICommand przez WPF XAML procesor w czasie ładowania).

Tworzenie poleceń niestandardowych

Jeśli polecenia z klas biblioteki poleceń nie spełniają Twoich potrzeb, możesz utworzyć własne polecenia. Istnieją dwa sposoby tworzenia polecenia niestandardowego. Pierwszy z nich zaczyna się od podstaw i implementuje ICommand interfejs. Innym sposobem i bardziej typowym podejściem jest utworzenie RoutedCommand lub RoutedUICommand .

Aby zapoznać się z przykładem tworzenia niestandardowego RoutedCommand , zobacz Tworzenie niestandardowego przykładu RoutedCommand.

Zobacz też