背景:私はWPFとC#(3.5)を使用しており、コンパイル済みアセンブリの一部であるフォーム/ウィンドウ/ユーザーコントロールをユーザーが表示できるようにするアプリに取り組んでいます。表示すると、任意のコントロール(ボタン、テキストボックス、さらにはラベル)をクリックできるはずです。コントロールの横に小さなポップアップエディタが表示され、そのコントロールのツールチップやhelpIDなどを入力できます。
その長所と短所:WPFの基本的なデザインビューを模倣する必要があります。つまり、少なくとも次のことを行う必要があります。
- 特定のアセンブリからユーザーコントロール/ウィンドウをロードします(問題ありません)
- ユーザーコントロール/ウィンドウをインスタンス化します(問題ありません)
- すべてのコントロールのサブスクライブされたすべてのEventHandlerをクリアします
- 自分の「ShowEditorPopup」EventHandlerを各コントロールに割り当てます(問題はないはずです)
まず、誰かがより簡単またはより良いルートについて提案があれば、私に知らせてください。(どうやら、WPF用のDesignHostの種類のコンポーネントはないので(.NET 2を読んだように)、それはありません。)
私は太字の項目で立ち往生しています-サブスクライブされたEventHandlerをクリアします。いくつかを掘り下げてReflectorに入った後、危険なコードのこのクールなチャンクを思いつきました(ここでは、XAMLで定義されたsomeButtonと呼ばれる単一のボタンのすべてのEventHandlerを取得しようとしています):
<Button Name="someButton" Click="someButton_Click"/>
コードは次のとおりです(必要に応じてsomeButton_Click eventHandlerから実行できます)。
public void SomeFunction()
{
// Get the control's Type
Type someButtonType = ((UIElement)someButton).GetType();
// Dig out the undocumented (yes, I know, it's risky) EventHandlerStore
// from the control's Type
PropertyInfo EventHandlersStoreType =
someButtonType.GetProperty("EventHandlersStore",
BindingFlags.Instance | BindingFlags.NonPublic);
// Get the actual "value" of the store, not just the reflected PropertyInfo
Object EventHandlersStore = EventHandlersStoreType.GetValue(someButton, null);
// Get the store's type ...
Type storeType = EventHandlersStore.GetType();
// ... so we can pull out the store's public method GetRoutedEventHandlers
MethodInfo GetEventHandlers =
storeType.GetMethod("GetRoutedEventHandlers",
BindingFlags.Instance | BindingFlags.Public);
// Reflector shows us that the method's sig is this:
// public RoutedEventHandlerInfo[] GetRoutedEventHandlers(RoutedEvent routedEvent);
// So set up the RoutedEvent param
object[] Params = new object[] { ButtonBase.ClickEvent as RoutedEvent };
// I've also seen this for the param, but doesn't seem to make a difference:
// object[] Params = new object[] { someButton.ClickEvent };
// And invoke it ... and watch it crash!
GetEventHandlers.Invoke(someButton, Params);
}
Invokeまで機能し、次を返します。オブジェクトがターゲットタイプと一致しません(つまり、パラメータまたはターゲットオブジェクトが混乱しています)。私はあなたがこれを解決できることを発見しました:
GetEventHandlers.Invoke(Activator.CreateInstance(someButton.GetType()), Params);
// Also doesn't work...
GetEventHandlers MethodInfoにウォッチを設定すると、見栄えが良くなります。Invokeを呼び出したときに渡すものが気に入らないだけです。
RoutedEventハンドラーのリストを取得する方法の最後のステップにいるように感じます(WPF RoutedEventsでは機能しない古き良きGetInvocationList()のようです)。そこから、各コントロールからこれらのハンドラーを削除し、イベントのないフォームを作成して、独自のイベントを追加するのは簡単です。
手がかりはありますか?繰り返しますが、タスク全体を実行するためのより良い/より簡単な方法がある場合は、私に知らせてください:)