Share via


Gambaran Umum Perintah

Perintah adalah mekanisme input di Windows Presentation Foundation (WPF) yang menyediakan penanganan input pada tingkat yang lebih semantik daripada input perangkat. Contoh perintah adalah operasi Salin, Potong, dan Tempel yang ditemukan di banyak aplikasi.

Gambaran umum ini mendefinisikan perintah apa yang ada di WPF, kelas mana yang merupakan bagian dari model perintah, dan cara menggunakan dan membuat perintah di aplikasi Anda.

Topik ini berisi bagian berikut:

Apa Itu Perintah

Perintah memiliki beberapa tujuan. Tujuan pertama adalah untuk memisahkan semantik dan objek yang memanggil perintah dari logika yang menjalankan perintah. Ini memungkinkan beberapa sumber yang berbeda untuk memanggil logika perintah yang sama, dan memungkinkan logika perintah disesuaikan untuk target yang berbeda. Misalnya, operasi pengeditan Salin, Potong, dan Tempel, yang ditemukan di banyak aplikasi, dapat dipanggil dengan menggunakan tindakan pengguna yang berbeda jika diimplementasikan dengan menggunakan perintah. Aplikasi mungkin memungkinkan pengguna untuk memotong objek atau teks yang dipilih dengan mengklik tombol, memilih item di menu, atau menggunakan kombinasi kunci, seperti CTRL+X. Dengan menggunakan perintah, Anda dapat mengikat setiap jenis tindakan pengguna ke logika yang sama.

Tujuan lain dari perintah adalah untuk menunjukkan apakah tindakan tersedia. Untuk melanjutkan contoh pemotongan objek atau teks, tindakan hanya masuk akal ketika sesuatu dipilih. Jika pengguna mencoba memotong objek atau teks tanpa memilih apa pun, tidak ada yang akan terjadi. Untuk menunjukkan hal ini kepada pengguna, banyak aplikasi menonaktifkan tombol dan item menu sehingga pengguna tahu apakah mungkin untuk melakukan tindakan. Perintah dapat menunjukkan apakah tindakan dimungkinkan dengan menerapkan CanExecute metode . Tombol dapat berlangganan CanExecuteChanged peristiwa dan dinonaktifkan jika CanExecute dikembalikan false atau diaktifkan jika CanExecute mengembalikan true.

Semantik perintah dapat konsisten di seluruh aplikasi dan kelas, tetapi logika tindakan khusus untuk objek tertentu yang ditindaklanjuti. Kombinasi kunci CTRL+X memanggil perintah Potong di kelas teks, kelas gambar, dan browser Web, tetapi logika aktual untuk melakukan operasi Potong ditentukan oleh aplikasi yang melakukan pemotongan. Memungkinkan RoutedCommand klien untuk mengimplementasikan logika. Objek teks dapat memotong teks terpilih ke clipboard, sementara objek gambar dapat memotong gambar yang dipilih. Ketika aplikasi menangani Executed peristiwa, aplikasi memiliki akses ke target perintah dan dapat mengambil tindakan yang sesuai tergantung pada jenis target.

Contoh Perintah Sederhana di WPF

Cara paling sederhana untuk menggunakan perintah di WPF adalah dengan menggunakan yang telah RoutedCommand ditentukan sebelumnya dari salah satu kelas pustaka perintah; gunakan kontrol yang memiliki dukungan asli untuk menangani perintah; dan menggunakan kontrol yang memiliki dukungan asli untuk memanggil perintah. Perintah Paste adalah salah satu perintah yang telah ditentukan sebelumnya di ApplicationCommands kelas . Kontrol TextBox telah dibangun dalam logika untuk menangani Paste perintah. MenuItem Dan kelas memiliki dukungan asli untuk memanggil perintah.

Contoh berikut menunjukkan cara menyiapkan MenuItem sehingga ketika diklik akan memanggil Paste perintah pada TextBox, dengan asumsi TextBox memiliki fokus keyboard.

<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

Empat Konsep Utama dalam Perintah WPF

Model perintah yang dirutekan di WPF dapat dipecah menjadi empat konsep utama: perintah, sumber perintah, target perintah, dan pengikatan perintah:

  • Perintah adalah tindakan yang akan dijalankan.

  • Sumber perintah adalah objek yang memanggil perintah.

  • Target perintah adalah objek tempat perintah dijalankan.

  • Pengikatan perintah adalah objek yang memetakan logika perintah ke perintah.

Dalam contoh sebelumnya, Paste perintah adalah perintah, MenuItem adalah sumber perintah, TextBox adalah target perintah, dan pengikatan perintah disediakan oleh TextBox kontrol. Perlu dicatat bahwa tidak selalu terjadi bahwa CommandBinding disediakan oleh kontrol yang merupakan kelas target perintah. Cukup sering CommandBinding harus dibuat oleh pengembang aplikasi, atau CommandBinding mungkin dilampirkan ke leluhur target perintah.

Perintah

Perintah di WPF dibuat dengan mengimplementasikan ICommand antarmuka. ICommand mengekspos dua metode, Execute, dan CanExecute, dan peristiwa, CanExecuteChanged. Execute melakukan tindakan yang terkait dengan perintah . CanExecute menentukan apakah perintah dapat dijalankan pada target perintah saat ini. CanExecuteChanged dimunculkan jika manajer perintah yang memusatkan operasi perintah mendeteksi perubahan sumber perintah yang mungkin membatalkan perintah yang telah dimunculkan tetapi belum dijalankan oleh pengikatan perintah. Implementasi ICommand WPF adalah RoutedCommand kelas dan merupakan fokus dari gambaran umum ini.

Sumber utama input dalam WPF adalah mouse, keyboard, tinta, dan perintah yang dirutekan. Semakin banyak input berorientasi perangkat menggunakan RoutedEvent untuk memberi tahu objek di halaman aplikasi bahwa peristiwa input telah terjadi. A RoutedCommand tidak berbeda. Metode Execute dan CanExecute dari tidak RoutedCommand berisi logika aplikasi untuk perintah, melainkan mereka menaikkan peristiwa rute yang terowongan dan gelembung melalui pohon elemen sampai mereka menemukan objek dengan CommandBinding. CommandBinding berisi handler untuk peristiwa ini dan merupakan handler yang melakukan perintah. Untuk informasi selengkapnya tentang perutean peristiwa di WPF, lihat Gambaran Umum Peristiwa Yang Dirutekan.

Metode Execute pada RoutedCommand meningkatkan PreviewExecuted dan Executed peristiwa pada target perintah. Metode CanExecute pada RoutedCommand meningkatkan CanExecute peristiwa dan PreviewCanExecute pada target perintah. Peristiwa ini terowongan dan gelembung melalui pohon elemen sampai mereka menemukan objek yang memiliki CommandBinding untuk perintah tertentu.

WPF menyediakan serangkaian perintah rute umum yang tersebar di beberapa kelas: MediaCommands, , ApplicationCommands, NavigationCommandsComponentCommands, dan EditingCommands. Kelas-kelas ini hanya terdiri dari RoutedCommand objek dan bukan logika implementasi perintah. Logika implementasi adalah tanggung jawab objek tempat perintah dijalankan.

Sumber Perintah

Sumber perintah adalah objek yang memanggil perintah. Contoh sumber perintah adalah MenuItem, , Buttondan KeyGesture.

Sumber perintah di WPF umumnya ICommandSource mengimplementasikan antarmuka.

ICommandSource mengekspos tiga properti: Command, CommandTarget, dan CommandParameter:

Kelas WPF yang mengimplementasikan adalah , , MenuItemHyperlink, dan InputBinding.ButtonBaseICommandSource ButtonBase, MenuItem, dan Hyperlink panggil perintah saat diklik, dan memanggil InputBinding perintah saat InputGesture yang terkait dengannya dilakukan.

Contoh berikut menunjukkan cara menggunakan MenuItem di ContextMenu sebagai sumber perintah untuk Properties perintah.

<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

Biasanya, sumber perintah akan mendengarkan peristiwa.CanExecuteChanged Kejadian ini menginformasikan sumber perintah bahwa kemampuan perintah untuk dijalankan pada target perintah saat ini mungkin telah berubah. Sumber perintah dapat mengkueri status saat ini dengan RoutedCommand menggunakan CanExecute metode . Sumber perintah kemudian dapat menonaktifkan dirinya sendiri jika perintah tidak dapat dijalankan. Contohnya adalah MenuItem berwarna abu-abu itu sendiri ketika perintah tidak dapat dijalankan.

Dapat InputGesture digunakan sebagai sumber perintah. Dua jenis gerakan input dalam WPF adalah KeyGesture dan MouseGesture. Anda dapat menganggap KeyGesture sebagai pintasan keyboard, seperti CTRL+C. KeyGesture Terdiri dari satu Key set dan satu set ModifierKeys. MouseGesture Terdiri dari satu MouseAction set ModifierKeysopsional dan .

Agar bertindak InputGesture sebagai sumber perintah, perintah harus dikaitkan dengan perintah. Ada beberapa cara untuk mencapai hal ini. Salah satu caranya adalah dengan menggunakan InputBinding.

Contoh berikut menunjukkan cara membuat KeyBinding antara dan KeyGestureRoutedCommand.

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

Cara lain untuk mengaitkan InputGesture ke a RoutedCommand adalah dengan menambahkan InputGesture ke InputGestureCollection pada RoutedCommand.

Contoh berikut menunjukkan cara menambahkan KeyGesture ke InputGestureCollection dari 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

Mengaitkan CommandBinding perintah dengan penanganan aktivitas yang mengimplementasikan perintah .

Kelas CommandBinding berisi Command properti, dan PreviewExecuted, Executed, , PreviewCanExecutedan CanExecute peristiwa.

Command adalah perintah yang CommandBinding sedang dikaitkan dengan. Penanganan aktivitas yang dilampirkan ke PreviewExecuted peristiwa dan Executed mengimplementasikan logika perintah. Penanganan aktivitas yang dilampirkan ke PreviewCanExecute peristiwa dan CanExecute menentukan apakah perintah dapat dijalankan pada target perintah saat ini.

Contoh berikut menunjukkan cara membuat CommandBinding di akar Window aplikasi. Mengaitkan CommandBindingOpen perintah dengan Executed dan CanExecute handler.

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

Selanjutnya, ExecutedRoutedEventHandler dan dibuat CanExecuteRoutedEventHandler . ExecutedRoutedEventHandler membuka yang MessageBox menampilkan string yang mengatakan perintah telah dijalankan. Mengatur CanExecuteRoutedEventHandler properti ke CanExecutetrue.

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

CommandBinding dilampirkan ke objek tertentu, seperti akar Window aplikasi atau kontrol. Objek yang CommandBinding dilampirkan untuk menentukan cakupan pengikatan. Misalnya, CommandBinding yang dilampirkan ke leluhur target perintah dapat dicapai oleh Executed peristiwa, tetapi CommandBinding yang dilampirkan ke turunan target perintah tidak dapat dicapai. Ini adalah konsekuensi langsung dari cara terowongan RoutedEvent dan gelembung dari objek yang meningkatkan peristiwa.

Dalam beberapa situasi CommandBinding , dilampirkan ke target perintah itu sendiri, seperti dengan TextBox kelas dan Cutperintah , Copy, dan Paste . Namun, lebih mudah untuk melampirkan ke leluhur CommandBinding target perintah, seperti objek utama Window atau Aplikasi, terutama jika hal yang sama CommandBinding dapat digunakan untuk beberapa target perintah. Ini adalah keputusan desain yang ingin Anda pertimbangkan ketika Anda membuat infrastruktur perintah Anda.

Target Perintah

Target perintah adalah elemen tempat perintah dijalankan. Sehubungan RoutedCommanddengan , target perintah adalah elemen di mana perutean Executed dan CanExecute dimulai. Seperti disebutkan sebelumnya, di WPF CommandTarget properti pada ICommandSource hanya berlaku ketika ICommand adalah RoutedCommand. CommandTarget Jika diatur pada dan ICommandSource perintah yang sesuai bukan RoutedCommand, target perintah diabaikan.

Sumber perintah dapat secara eksplisit mengatur target perintah. Jika target perintah tidak ditentukan, elemen dengan fokus keyboard akan digunakan sebagai target perintah. Salah satu manfaat menggunakan elemen dengan fokus keyboard sebagai target perintah adalah memungkinkan pengembang aplikasi menggunakan sumber perintah yang sama untuk memanggil perintah pada beberapa target tanpa harus melacak target perintah. Misalnya, jika MenuItemmemanggil perintah Tempel dalam aplikasi yang memiliki TextBox kontrol dan PasswordBox kontrol, target dapat berupa TextBox atau PasswordBox tergantung pada kontrol mana yang memiliki fokus keyboard.

Contoh berikut menunjukkan cara secara eksplisit mengatur target perintah dalam markup dan dalam kode di belakang.

<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

melayani CommandManager sejumlah fungsi terkait perintah. Ini menyediakan sekumpulan metode statis untuk menambahkan dan menghapus PreviewExecuted, , ExecutedPreviewCanExecute, dan CanExecute penanganan aktivitas ke dan dari elemen tertentu. Ini menyediakan sarana untuk mendaftar CommandBinding dan InputBinding objek ke kelas tertentu. juga CommandManager menyediakan sarana, melalui RequerySuggested peristiwa, untuk memberi tahu perintah kapan harus menaikkan CanExecuteChanged peristiwa.

Metode ini InvalidateRequerySuggested memaksa CommandManager untuk menaikkan RequerySuggested peristiwa. Ini berguna untuk kondisi yang harus menonaktifkan/mengaktifkan perintah tetapi bukan kondisi yang CommandManager diperhatikan.

Pustaka Perintah

WPF menyediakan sekumpulan perintah yang telah ditentukan sebelumnya. Pustaka perintah terdiri dari kelas berikut: ApplicationCommands, , NavigationCommandsMediaCommands, EditingCommands, dan ComponentCommands. Kelas-kelas ini menyediakan perintah seperti Cut, dan BrowseBackBrowseForward, Play, Stop, dan Pause.

Banyak dari perintah ini termasuk sekumpulan pengikatan input default. Misalnya, jika Anda menentukan bahwa aplikasi Anda menangani perintah salin, Anda secara otomatis mendapatkan pengikatan keyboard "CTRL+C" Anda juga mendapatkan pengikatan untuk perangkat input lainnya, seperti gerakan pena PC Tablet dan informasi ucapan.

Saat Anda mereferensikan perintah di berbagai pustaka perintah menggunakan XAML, Anda biasanya dapat menghilangkan nama kelas kelas pustaka yang mengekspos properti perintah statis. Umumnya, nama perintah tidak ambigu sebagai string, dan jenis pemilik ada untuk menyediakan pengelompokan perintah yang logis tetapi tidak diperlukan untuk disambiguasi. Misalnya, Anda dapat menentukan Command="Cut" daripada yang lebih verbose Command="ApplicationCommands.Cut". Ini adalah mekanisme kenyamanan yang dibangun dalam prosesor WPF XAML untuk perintah (lebih tepatnya, ini adalah perilaku ICommandpengonversi jenis , yang dirujuk prosesor WPF XAML pada waktu pemuatan).

Membuat Perintah Kustom

Jika perintah di kelas pustaka perintah tidak memenuhi kebutuhan Anda, maka Anda dapat membuat perintah Anda sendiri. Ada dua cara untuk membuat perintah kustom. Yang pertama adalah memulai dari bawah ke atas dan mengimplementasikan ICommand antarmuka. Cara lain, dan pendekatan yang lebih umum, adalah membuat RoutedCommand atau RoutedUICommand.

Untuk contoh pembuatan kustom RoutedCommand, lihat Membuat Sampel RoutedCommand Kustom.

Baca juga