背景:我正在使用WPF和C#(3.5),并且正在开发一个应用程序,该应用程序允许用户查看已经是编译程序集的一部分的窗体/窗口/用户控件。当他们查看它时,他们应该能够点击任何控件(按钮,文本框,甚至标签),控件上应该出现一个小小的弹出窗口编辑器,然后可以在该控件中输入工具提示,helpID等。通过反射去除路由事件处理程序?
它的长短:我需要模仿WPF中的基本设计视图。这意味着我至少需要做到以下几点:
- 负载从一个给定的装配(没问题)的用户控件/窗口
- 中实例化用户控件/窗口(没问题)
- 清除其所有控制
- 指定我自己的“ShowEditorPopup”事件处理程序,以每个控制所有订阅的事件处理器(不应该是一个问题)
首先,如果有人对更简单或更好的路线有任何建议,请让我知道。 (显然,WPF没有DesignHost类型的组件(就像我已经读过.NET 2一样),所以这是不可能的。)
我被困在粗体项目 - 清除任何订阅的EventHandlers。在挖掘了一些并进入Reflector之后,我想出了这个很酷的危险代码块(在这里,我只是想让所有的EventHandlers在XAML中定义一个叫someButton的Button):
<Button Name="someButton" Click="someButton_Click"/>
下面的代码(你可以,如果你想从someButton_Click事件处理程序运行它):
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);
}
它的工作原理到调用,它返回:对象不匹配目标类型(即我params中,目标对象被弄乱)。我发现你可以解决此问题:
GetEventHandlers.Invoke(Activator.CreateInstance(someButton.GetType()), Params);
// Also doesn't work...
当我设置监视那个GetEventHandlers的MethodInfo,它看起来很棒,它只是不喜欢什么,我路过它时,我所说的调用。
我觉得我在最后一步如何获得RoutedEvent处理程序的列表(如旧的GetInvocationList(),显然不适用于WPF RoutedEvents)。从那里,它将会非常简单,从每个控件中移除这些处理程序,并拥有一个无事件形式,然后我可以添加自己的事件。
任何线索?再次,如果有更好/更简单的方法来完成整个任务,请让我知道:)
哇,你是一个伟大的工作,我只是想这样做。你只是给了我需要的出发点。 – orellabac 2013-04-06 17:44:32