特定のコマンドを処理するために CommandBindings コレクションに CommandBinding を追加する UserControl があります。後で、このコントロールをウィンドウで使用し、同じコントロールに別のバインディングを追加して、追加の動作を追加したいと考えています。ただし、問題は、これを行うと、別の CommandBinding をコントロールの CommandBindings コレクションに追加すると、同じコマンドに対して既に作成されているバインディングが置き換えられるように見えることです。コントロールは、コントロールごとに 1 つの CommandBinding しか持つことができないように見えますが、これは正しいですか?
同じ保存コマンドに対して 2 つの CommandBinding を設定しようとする以下のコード例を参照してください。
<Window x:Class="MultipleCommandBindings.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.CommandBindings>
<CommandBinding Command="Save"
Executed="CommandBinding_Executed" />
<CommandBinding Command="Save"
Executed="CommandBinding_Executed" />
</Window.CommandBindings>
<Grid>
<Button Height="23"
HorizontalAlignment="Right"
Margin="0,0,25,88"
Name="button1"
VerticalAlignment="Bottom"
Width="75"
Command="Save">Button</Button>
</Grid>
もともと、このコードを書いたとき、コンパイル時または実行時例外のいずれかを予期していましたが、文句を言わなかったことに驚きました。次に、 CommandBinding_Executed ハンドラーが 2 回ではなく 1 回しか呼び出されないので、期待していたのにがっかりしました。
更新: 少しテストした後、2 番目の CommandBinding が最初の CommandBinding を上書きしていないように見えますが、代わりに、イベント ハンドラーで Handled を true に設定していなくても、最初のコマンド バインディングが Command を飲み込んでいるように見えます。この時点で、私の問題の解決策は、Handled が true に設定されていない場合でも、ルーティングされたコマンドが最初のハンドラーを超えて伝播しない理由を理解することであると確信しています。
更新: WPF でのコマンド ルーティングの背後にある奇妙な動作のいくつかを確認する、このちょっとした情報を 見つけました。
更新: コマンドごとに 1 つの有効な CommandBinding しか存在できないように見えるという事実を回避する方法についての 1 つの考えは、デフォルトの CommandBinding クラスが Executed および CanExecute をイベントとして公開しているように見えることです。もちろん、すべてのイベントと同様に複数のハンドラーを持つことができます。 . その場合のアイデアは、標準の CommandBindings.Add メソッド以外の方法を使用して、追加のハンドラーをコマンドに追加することです。おそらく、これは Control クラスの拡張メソッドを介して実行でき、カスタムの CompositeCommandBinding クラスと組み合わせて、1 つのメイン バインディング内に複数のバインディングを集約できます。