Komut Vermeye Genel Bakış

Komut, Windows Presentation Foundation'da (WPF) cihaz girişinden daha anlamsal düzeyde giriş işleme sağlayan bir giriş mekanizmasıdır. Komutlara örnek olarak birçok uygulamada bulunan Kopyala, Kes ve Yapıştır işlemleri verilebilir.

Bu genel bakış, WPF'de hangi komutların olduğunu, hangi sınıfların komut modelinin parçası olduğunu ve uygulamalarınızda komutların nasıl kullanılacağını ve oluşturulacağını tanımlar.

Bu konu, aşağıdaki bölümleri içerir:

Komutlar Nelerdir?

Komutların çeşitli amaçları vardır. İlk amaç, semantiği ve komutu çağıran nesneyi komutu yürüten mantıktan ayırmaktır. Bu, birden çok ve farklı kaynağın aynı komut mantığını çağırmasına olanak tanır ve komut mantığının farklı hedefler için özelleştirilmesine olanak tanır. Örneğin, birçok uygulamada bulunan Kopyalama, Kesme ve Yapıştırma düzenleme işlemleri, komutlar kullanılarak uygulanıyorsa farklı kullanıcı eylemleri kullanılarak çağrılabilir. Uygulama, kullanıcının bir düğmeye tıklayarak, menüden bir öğe seçerek veya CTRL+X gibi bir tuş bileşimi kullanarak seçili nesneleri veya metni kesmesine izin verebilir. Komutları kullanarak her kullanıcı eylemi türünü aynı mantığa bağlayabilirsiniz.

Komutların bir diğer amacı da bir eylemin kullanılabilir olup olmadığını belirtmektir. Nesne veya metin kesme örneğine devam etmek için, eylem yalnızca bir şey seçildiğinde mantıklı olur. Kullanıcı hiçbir şey seçmeden bir nesneyi veya metni kesmeye çalışırsa hiçbir şey olmaz. Bunu kullanıcıya göstermek için, birçok uygulama düğmeleri ve menü öğelerini devre dışı bırakır, böylece kullanıcı eylem gerçekleştirmenin mümkün olup olmadığını bilir. Komut, yöntemini uygulayarak bir eylemin CanExecute mümkün olup olmadığını gösterebilir. Bir düğme olaya abone CanExecuteChanged olabilir ve döndürürse falseCanExecute devre dışı bırakılabilir veya döndürürse CanExecutetrueetkinleştirilebilir.

Bir komutun semantiği uygulamalar ve sınıflar arasında tutarlı olabilir, ancak eylemin mantığı üzerinde işlem yapılan belirli nesneye özgüdür. CTRL+X tuş bileşimi metin sınıflarında, görüntü sınıflarında ve Web tarayıcılarında Kes komutunu çağırır, ancak Kesme işlemini gerçekleştirmek için gerçek mantık kesme işlemini gerçekleştiren uygulama tarafından tanımlanır. A RoutedCommand , istemcilerin mantığı uygulamasına olanak tanır. Metin nesnesi seçili metni panoya kesebilirken, resim nesnesi seçili görüntüyü kesebilir. Bir uygulama olayı işlediğinde Executed , komutun hedefine erişebilir ve hedefin türüne bağlı olarak uygun eylemi gerçekleştirebilir.

WPF'de Basit Komut Örneği

WPF'de komut kullanmanın en basit yolu, komut kitaplığı sınıflarından birinden önceden tanımlanmış RoutedCommand bir denetim kullanmak; komutu işlemek için yerel desteğe sahip bir denetim kullanmak ve komutu çağırmak için yerel desteğe sahip bir denetim kullanmaktır. Paste komutu, sınıfındaki önceden tanımlanmış komutlardan ApplicationCommands biridir. Denetimin TextBox , komutu işlemek Paste için yerleşik mantığı vardır. Ayrıca sınıfı, MenuItem komutları çağırmak için yerel desteğe sahiptir.

Aşağıdaki örnekte, klavye odağının olduğu varsayılarak TextBox tıklandığında komutun üzerinde TextBoxçağrılması Paste için nasıl ayarlanacağı MenuItem gösterilmektedir.

<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

WPF Komutlarında Dört Ana Kavram

WPF'de yönlendirilen komut modeli dört ana kavrama ayrılabilir: komut, komut kaynağı, komut hedefi ve komut bağlaması:

  • Komut yürütülecek eylemdir.

  • Komut kaynağı , komutu çağıran nesnedir.

  • Komut hedefi , komutun yürütülmekte olduğu nesnedir.

  • Komut bağlaması, komut mantığını komutla eşleyen nesnedir.

Önceki örnekte Paste komut komutudur, MenuItem komut kaynağıdır, TextBox komut hedefidir ve komut bağlaması denetim tarafından TextBox sağlanır. her zaman komut hedef sınıfı olan denetim tarafından sağlanan durum CommandBinding olmadığını belirtmek gerekir. Genellikle uygulama CommandBinding geliştiricisi tarafından oluşturulması gerekir veya CommandBinding komut hedefinin bir atası eklenebilir.

Komutlar

WPF'deki komutlar arabirimi uygulanarak ICommand oluşturulur. ICommand , ve ve adlı iki yöntemi Executeve CanExecutebir olayı kullanıma sunar: CanExecuteChanged. Execute komutuyla ilişkili eylemleri gerçekleştirir. CanExecute komutun geçerli komut hedefinde yürütülip yürütülemeyeceğini belirler. CanExecuteChanged , komut işlemlerini merkezileştiren komut yöneticisi komut kaynağında, komut bağlaması tarafından oluşturulmuş ancak henüz yürütülmemiş bir komutu geçersiz kabilecek bir değişiklik algılarsa oluşturulur. WPF uygulaması ICommand sınıfıdır RoutedCommand ve bu genel bakışın odağıdır.

WPF'deki ana giriş kaynakları fare, klavye, mürekkep ve yönlendirilmiş komutlardır. Cihaz odaklı girişler, uygulama sayfasındaki nesnelere bir giriş olayının gerçekleştiğini bildirmek için kullanır RoutedEvent . A RoutedCommand farklı değildir. Execute ve CanExecute yöntemleri RoutedCommand komutu için uygulama mantığını içermez, ancak bunun yerine ile bir nesnesiyle CommandBindingkarşılaşana kadar öğe ağacında tünel ve kabarcık oluşturan yönlendirilmiş olaylar oluştururlar. CommandBinding, bu olayların işleyicilerini içerir ve komutu gerçekleştiren işleyicileridir. WPF'de olay yönlendirme hakkında daha fazla bilgi için bkz . Yönlendirilmiş Olaylara Genel Bakış.

üzerindeki Execute yöntemi RoutedCommand , komut hedefinde PreviewExecutedExecuted ve olaylarını yükseltir. üzerindeki CanExecuteRoutedCommand yöntemi, komut hedefinde CanExecute ve PreviewCanExecute olaylarını yükseltir. Bu olaylar, belirli bir komut için bir nesnesine sahip CommandBinding bir nesneyle karşılaşana kadar öğe ağacında tünel oluşturur ve kabarcık oluşturur.

WPF, çeşitli sınıflara yayılmış bir dizi ortak yönlendirilmiş komut sağlar: MediaCommands, ApplicationCommands, NavigationCommands, ComponentCommandsve EditingCommands. Bu sınıflar komutun RoutedCommand uygulama mantığından değil yalnızca nesnelerden oluşur. Uygulama mantığı, komutun yürütülmekte olduğu nesnenin sorumluluğundadır.

Komut Kaynakları

Komut kaynağı, komutu çağıran nesnedir. Komut kaynaklarına örnek olarak MenuItem, Buttonve KeyGestureverilebilir.

WPF'deki komut kaynakları genellikle arabirimini ICommandSource uygular.

ICommandSource üç özelliği kullanıma sunar: Command, CommandTargetve CommandParameter:

Uygulayan ICommandSource WPF sınıfları , MenuItem, Hyperlinkve InputBindingşeklindedirButtonBase. ButtonBase, MenuItemve Hyperlink tıklandığında bir komut çağırın ve ile ilişkilendirilmiş olan gerçekleştirildiğinde InputGesture bir InputBinding komut çağırır.

Aşağıdaki örnekte, içinde komutunun MenuItemContextMenu komut kaynağı olarak nasıl kullanılacağı gösterilmektedir 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

Genellikle bir komut kaynağı olayı dinler CanExecuteChanged . Bu olay, komutun geçerli komut hedefinde yürütülebilme özelliğinin değişmiş olabileceğini komut kaynağına bildirir. Komut kaynağı yöntemini kullanarak CanExecute öğesinin RoutedCommand geçerli durumunu sorgulayabilir. Komut yürütülemezse komut kaynağı kendisini devre dışı bırakabilir. Bunun bir örneği, bir MenuItem komut yürütülemediğinde gri görünen bir durumdur.

bir InputGesture komut kaynağı olarak kullanılabilir. WPF'de iki tür giriş hareketi ve MouseGestureşeklindedirKeyGesture. CTRL+C gibi bir klavye kısayolu olarak düşünebilirsiniz KeyGesture . A KeyGesture , bir Key ve kümesinden ModifierKeysoluşur. A MouseGesture , ve MouseAction isteğe bağlı bir kümesinden ModifierKeysoluşur.

komut InputGesture kaynağı olarak davranabilmesi için bir komutla ilişkilendirilmesi gerekir. Bunu yapmanın birkaç yolu vardır. Bunun bir yolu, kullanmaktır InputBinding.

Aşağıdaki örnekte ile arasında KeyGesture bir KeyBinding oluşturma gösterilmektedirRoutedCommand.

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

ile ilişkilendirmenin başka bir InputGesture yolu da üzerinde öğesine eklemektir InputGestureInputGestureCollectionRoutedCommand.RoutedCommand

Aşağıdaki örnekte bir öğesine nasıl ekleneceği KeyGestureInputGestureCollection gösterilmektedir 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

komutu CommandBinding , komutu uygulayan olay işleyicileriyle ilişkilendirir.

CommandBinding sınıfı bir Command özellik ve PreviewExecuted, Executed, PreviewCanExecuteve CanExecute olayları içerir.

Command , ile ilişkilendirilmekte olan CommandBinding komutdur. ve Executed olaylarına PreviewExecuted eklenen olay işleyicileri komut mantığını uygular. ve CanExecute olaylarına PreviewCanExecute eklenen olay işleyicileri, komutun geçerli komut hedefinde yürütülip yürütülemediğini belirler.

Aşağıdaki örnekte, bir uygulamanın kökünde Window nasıl oluşturulacağı CommandBinding gösterilmektedir. komutu CommandBinding ve ExecutedCanExecute işleyicileriyle ilişkilendirirOpen.

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

Ardından ve ExecutedRoutedEventHandlerCanExecuteRoutedEventHandler oluşturulur. komutu ExecutedRoutedEventHandler , komutun yürütüldüğünü belirten bir dize görüntüleyen bir MessageBox açar. CanExecuteRoutedEventHandler özelliğini olarak CanExecutetrueayarlar.

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 uygulamanın kökü Window veya denetim gibi belirli bir nesneye eklenir. öğesinin CommandBinding eklendiği nesne bağlamanın kapsamını tanımlar. Örneğin, CommandBinding komut hedefinin bir atasına bağlı olan bir olaya olay tarafından Executed ulaşılabilir, ancak CommandBinding komut hedefinin alt öğesine iliştirilmiş bir öğeye ulaşılamaz. Bu, olayı oluşturan nesneden tüneller ve kabarcıklar oluşturmanın doğrudan bir RoutedEvent sonucudur.

Bazı durumlardaCommandBinding, sınıfı ve , Copyve Paste komutları gibi komut hedefinin TextBoxCutkendisine eklenir. Yine de, özellikle aynı CommandBinding birden çok komut hedefi için kullanılabiliyorsa, öğesini ana Window veya Uygulama nesnesi gibi komut hedefinin bir atası olarak eklemek CommandBinding daha uygundur. Bunlar, komut altyapınızı oluştururken dikkate almak isteyeceğiniz tasarım kararlarıdır.

Komut Hedefi

Komut hedefi, komutun yürütüldiği öğedir. ile RoutedCommandilgili olarak, komut hedefi ve CanExecute yönlendirmesinin Executed başlatıldığı öğedir. Daha önce belirtildiği gibi, WPF'de CommandTarget üzerindeki ICommandSource özelliği yalnızca bir olduğunda ICommandRoutedCommandgeçerlidir. CommandTarget bir üzerinde ICommandSource ayarlanırsa ve buna karşılık gelen komut bir RoutedCommanddeğilse, komut hedefi yoksayılır.

Komut kaynağı, komut hedefini açıkça ayarlayabilir. Komut hedefi tanımlanmamışsa, komut hedefi olarak klavye odağına sahip öğe kullanılır. Komut hedefi olarak klavye odağıyla öğesini kullanmanın avantajlarından biri, uygulama geliştiricisinin komut hedefini izlemek zorunda kalmadan birden çok hedefte bir komut çağırmak için aynı komut kaynağını kullanmasına izin vermesidir. Örneğin, bir MenuItem denetimi ve PasswordBox denetimi olan TextBox bir uygulamada Yapıştır komutunu çağırırsa hedef, klavye odağının bulunduğu denetime TextBox bağlı olarak veya PasswordBox olabilir.

Aşağıdaki örnekte, işaretlemede ve arkasındaki kodda komut hedefinin açıkça nasıl ayarlanacağı gösterilmektedir.

<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

, CommandManager komutla ilgili bir dizi işleve hizmet eder. Belirli bir öğeye ve öğeden , Executed, PreviewCanExecuteve olay işleyicileri eklemek ve CanExecute kaldırmak PreviewExecutediçin bir dizi statik yöntem sağlar. Belirli bir sınıfa ve InputBinding nesneleri kaydetmek CommandBinding için bir araç sağlar. ayrıca CommandManager , olay aracılığıyla RequerySuggested bir komutun olayı ne zaman tetiklemesi CanExecuteChanged gerektiğini bildirmek için bir yol sağlar.

yöntemi, InvalidateRequerySuggested olayını CommandManager tetiklemeye zorlar RequerySuggested . Bu, bir komutu devre dışı bırakması/etkinleştirmesi gereken koşullar için yararlıdır, ancak bunun farkında olduğu koşullar CommandManager değildir.

Komut Kitaplığı

WPF önceden tanımlanmış bir komut kümesi sağlar. Komut kitaplığı şu sınıflardan oluşur: ApplicationCommands, NavigationCommands, MediaCommands, EditingCommandsve .ComponentCommands Bu sınıflar , ve , BrowseBack , PlayStopve BrowseForwardPausegibi Cutkomutlar sağlar.

Bu komutların çoğu bir dizi varsayılan giriş bağlaması içerir. Örneğin, uygulamanızın kopyalama komutunu işlediğini belirtirseniz, "CTRL+C" klavye bağlamasını otomatik olarak alırsınız. Ayrıca Tablet PC kalem hareketleri ve konuşma bilgileri gibi diğer giriş cihazları için bağlamalar da alırsınız.

XAML kullanarak çeşitli komut kitaplıklarındaki komutlara başvurduğunuz zaman, genellikle statik komut özelliğini kullanıma sunan kitaplık sınıfının sınıf adını atlayabilirsiniz. Genellikle, komut adları dizeler olarak belirsizdir ve komutlardan oluşan mantıksal bir gruplandırma sağlamak için sahip olan türler vardır, ancak kesinleştirme için gerekli değildir. Örneğin, daha ayrıntılı Command="ApplicationCommands.Cut"yerine belirtebilirsinizCommand="Cut". Bu, komutlar için WPF XAML işlemcisinde yerleşik olarak bulunan bir kolaylık mekanizmasıdır (daha kesin olarak, WPF XAML işlemcisinin ICommandyükleme zamanında başvurduğunu türü dönüştürücü davranışıdır).

Özel Komutlar Oluşturma

Komut kitaplığı sınıflarındaki komutlar gereksinimlerinizi karşılamıyorsa kendi komutlarınızı oluşturabilirsiniz. Özel komut oluşturmanın iki yolu vardır. İlki sıfırdan başlayıp arabirimi uygulamaktır ICommand . Diğer yol ve daha yaygın yaklaşım, veya RoutedUICommandoluşturmaktırRoutedCommand.

Özel RoutedCommandoluşturma örneği için bkz . Özel Yönlendirilmiş Komut Örneği Oluşturma.

Ayrıca bkz.