方法: コマンドをサポートしないコントロールにコマンドをフックする

次の例では、コマンドのサポートが組み込まれていない ControlRoutedCommand をフックする方法を示します。 コマンドを複数のソースに関連付けるサンプル全体については、「カスタム RoutedCommand の作成のサンプル」を参照してください。

Windows Presentation Foundation (WPF) には、アプリケーション プログラマがよく使用する一般的なコマンドのライブラリが用意されています。 コマンド ライブラリを構成するクラスは、ApplicationCommandsComponentCommandsNavigationCommandsMediaCommandsEditingCommands です。

これらのクラスを構成する静的な RoutedCommand オブジェクトには、コマンド ロジックが用意されていません。 コマンドのロジックは、CommandBinding でコマンドに関連付けられます。 WPF の多くのコントロールには、コマンド ライブラリにある一部のコマンドのサポートが組み込まれています。 たとえば、TextBox では、PasteCopyCutRedoUndo などの多くのアプリケーション編集コマンドがサポートされます。 アプリケーション開発者は、コントロールで使用するこれらのコマンドを取得するのに特別な作業を行う必要はありません。 TextBox がコマンド ターゲットである場合は、コマンドを実行すると、コントロールに組み込まれている CommandBinding を使用してコマンドが処理されます。

Open コマンドのコマンド ソースとして Button を使用する方法を以下に示します。 CommandBinding が作成され、指定された CanExecuteRoutedEventHandlerCanExecuteRoutedEventHandlerRoutedCommand に関連付けられます。

まず、コマンド ソースが作成されます。 Button はコマンド ソースとして使用されます。

<Button Command="ApplicationCommands.Open" Name="MyButton"
        Height="50" Width="200">
  Open (KeyBindings: Ctrl+R, Ctrl+0)
</Button>
// Button used to invoke the command
Button CommandButton = new Button();
CommandButton.Command = ApplicationCommands.Open;
CommandButton.Content = "Open (KeyBindings: Ctrl-R, Ctrl-0)";
MainStackPanel.Children.Add(CommandButton);
' Button used to invoke the command
Dim CommandButton As New Button()
CommandButton.Command = ApplicationCommands.Open
CommandButton.Content = "Open (KeyBindings: Ctrl-R, Ctrl-0)"
MainStackPanel.Children.Add(CommandButton)

次に、ExecutedRoutedEventHandlerCanExecuteRoutedEventHandler が作成されます。 ExecutedRoutedEventHandler では単に MessageBox が開かれ、コマンドが実行されたことが示されます。 CanExecuteRoutedEventHandlerCanExecute プロパティを 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);
}
void OpenCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}


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
Private Sub OpenCmdCanExecute(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
    e.CanExecute = True
End Sub

最後に、CommandBinding がアプリケーションのルート Window に作成され、Open コマンドにルーティング イベント ハンドラーが関連付けられます。

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

関連項目