2011-07-18 7 views
1

WPF MenuItemを他の情報のない関数から返しました。別の(新しい)MenuItemのクリックイベントを、最初のMenuItemと同じ機能に設定します。あるコントロールから別のコントロールにRoutedEventハンドラをコピーする

Windowsフォームでこれを行うコード(例:Is it possible to "steal" an event handler from one control and give it to another?)がありますが、WPFルーティングイベントの解決策が見つかりません。

答えて

0

WPFでメニューアイテムをコピーする必要があるときは、私はコマンドパターンを示唆していますが、賢明なトリッキーでもイベントハンドラをサポートすることができます(下記参照)。

MenuItem copy = new MenuItem(); 
copy.Header = item.Header; 
copy.Icon = item.Icon; 
copy.Command = item.Command; 
copy.CommandParameter = item.CommandParameter; 
foreach(CommandBinding binding in item.CommandBindings) { 
    copy.CommandBindings.Add(binding); 
} 
newCollection.Add(copy); 

を明らかにあなたは、あなたが傾向があるのMenuItemの機能に応じて、コピーするプロパティを微調整する必要がある場合があります:私はアイテムをコピーするために使用するコードはこのような何か、「アイテム」は古いのMenuItemここで私はコピーしていますが見えます使用する。私はかなりHeader、Icon、Commandに固執しているので、それはすべて私が実装したものです。

イベントハンドラスタイルをサポートする必要がある場合は、イベントに割り当てる前に「再生」できるだけなので、何らかの抽象化が必要になります。メニュー項目にイベントハンドラを追加すると、かなり取り戻せなくなります。あなたがが(事前申し込み)実際のRoutedEventHandlerオブジェクトを持っている場合は、この小さな回避策を行うことができます(「ハンドラは」私はラップしていますRoutedEventHandlerインスタンスです):

ExecutedRoutedEventHandler executed = (sender, args) => 
{ 
    RoutedEventArgs innerArgs = new RoutedEventArgs(); 
    // The consumer probably shouldn't rely on these, but we'll copy them for completeness sake 
    innerArgs.RoutedEvent = args.RoutedEvent; 
    innerArgs.Handled = args.Handled; 
    innerArgs.Source = args.Source; 
    handler.Invoke(sender, innerArgs); 
}; 
RoutedUICommand cmd = new RoutedUICommand("Temp", "Temp", this.GetType()); 
newItem.CommandBindings.Add(new CommandBinding(cmd, executed)); 
newItem.Command = cmd; 

あなたは

を交換する必要があるかもしれません
this.GetType() 

他のものは、メニュー項目を構成するコンテキストによって異なります。私は視覚的なツリー(私の場合、コンテキストメニュー項目をコピーしているオブジェクト)のMenuItemの最終的な親になるオブジェクトの型である必要があると思う。

関連する問題