WinRT (Windows 8) アプリで MVVM を使用したいのですが、私の要件の 1 つは、イベントをコマンド ( ICommand
) にフックできるようにすることです。これは、ハンドラーを WinRT イベントに動的に追加する必要があることを意味します。here でそれを行う方法についての素晴らしい説明がありますが、私の問題は、コンパイル時にハンドラーのタイプが不明であることです(つまり、常にRoutedEventHandler
その例のようになるとは限りません)。
そのコードの一般的な実装を書き始め、式ツリーを使用してデリゲートを構築しました。その部分は機能します。私の問題は、動的に呼び出すことWindowsRuntimeMarshal.AddEventHandler
が失敗することです:
var rtMarshalType = typeof (WindowsRuntimeMarshal);
var eventHandlerMethod = rtMarshalType.GetRuntimeMethods().Single(x => x.IsStatic && x.Name == "AddEventHandler");
MethodInfo closedAddMethod = eventHandlerMethod.MakeGenericMethod(handlerType);
closedAddMethod.Invoke(null, new object[] {add, remove, handler});
これは呼び出しに失敗し、Invoke
次のメッセージとともに InvalidOperationException をスローします。
API 'System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.AddEventHandler[ItemClickEventHandler](System.Func
2[Windows.UI.Xaml.Controls.ItemClickEventHandler,System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken], System.Action
1[System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken], Windows.UI.Xaml.Controls.ItemClickEventHandler)' は、現在のプラットフォーム。詳細については、http: //go.microsoft.com/fwlink/?LinkId=248273を参照 してください。
上記の 4 行のコードをこれに置き換えると (イベント ハンドラーの型をハードコーディングしますが、これは私が望んでいるものではありません)、コードが機能し、イベントが期待どおりにアタッチされるため、適切な型があることはわかっています。
WindowsRuntimeMarshal.AddEventHandler<ItemClickEventHandler>(add, remove, handler);
参考までに、3 つのパラメーターは次のように定義されています (確かに、これは私の式ツリー構築コードの問題ではありません。私は現在、これらのデリゲートの明示的な定義を動的に呼び出しようAddEventHandler
としてもまだ失敗しています):
Func<ItemClickEventHandler, EventRegistrationToken> add =
a => (EventRegistrationToken) eventInfo.AddMethod.Invoke(instance, new object[] {a});
Action<EventRegistrationToken> remove = a => eventInfo.RemoveMethod.Invoke(instance, new object[] {a});
ItemClickEventHandler handler = (s, args) => command.Execute(args);
直接呼び出したときではなく、リフレクションを介して呼び出されたときに呼び出しが失敗するのはなぜですか?
コンパイル時にイベント ハンドラーのタイプがわからない場合、WinRT イベントを動的にアタッチするための代替ソリューションはありますか?