无论有没有反射,System.Windows.Interactivity.EventTrigger.EventName 如何有效工作?

发布于 2024-10-19 19:13:39 字数 1876 浏览 1 评论 0原文

我看到 System.Windows.Interactivity.EventTrigger.EventName 接受一个字符串。另外,我想他们需要通过反射来连接该事件。

但反射的名声有点不好,尤其是在性能方面,因此 System.Windows.Interactivity.EventTrigger。那么下面的代码是连接事件的最有效方法吗?Expression Blend 的 SDK 是否做了一些特别的事情?

public class EventToCommand
{
    public static readonly DependencyProperty EventNameProperty = DependencyProperty.RegisterAttached("EventName", typeof(string), typeof(EventToCommand), new UIPropertyMetadata(OnEventHandlerChanged));

    public static string GetEventName(DependencyObject obj)
    {
        return (string)obj.GetValue(EventNameProperty);
    }

    public static void SetEventName(DependencyObject obj, string value)
    {
        obj.SetValue(EventNameProperty, value);
    }

    private static void OnEventHandlerChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        Type objType = obj.GetType();
        var info = objType.GetEvent((string)args.NewValue);

        MethodInfo handler = typeof(EventToCommand).GetMethod("OnEventHandlerRaised", BindingFlags.Instance | BindingFlags.NonPublic);
        var o = Activator.CreateInstance(typeof(EventToCommand));
        Delegate d = Delegate.CreateDelegate(info.EventHandlerType, o, handler);
        MethodInfo addHandler = info.GetAddMethod();
        object[] addHandlerArgs = { d };
        addHandler.Invoke(obj, addHandlerArgs);
    }

    private void OnEventHandlerRaised(object sender, EventArgs args)
    {
        // Is it a unique instance?
        Console.WriteLine(value);
    }

    Guid value = Guid.NewGuid();
    public EventToCommand()
    {
    }
}

I see that the System.Windows.Interactivity.EventTrigger.EventName takes in a string. Also, I would imagine they need to hook up to that event via reflection.

But reflection has a bit of a bad name especially with performance, so are there performance issues with the System.Windows.Interactivity.EventTrigger. So is the code below the most efficient way to hook up to an event and is Expression Blend's SDK doing something special?

public class EventToCommand
{
    public static readonly DependencyProperty EventNameProperty = DependencyProperty.RegisterAttached("EventName", typeof(string), typeof(EventToCommand), new UIPropertyMetadata(OnEventHandlerChanged));

    public static string GetEventName(DependencyObject obj)
    {
        return (string)obj.GetValue(EventNameProperty);
    }

    public static void SetEventName(DependencyObject obj, string value)
    {
        obj.SetValue(EventNameProperty, value);
    }

    private static void OnEventHandlerChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        Type objType = obj.GetType();
        var info = objType.GetEvent((string)args.NewValue);

        MethodInfo handler = typeof(EventToCommand).GetMethod("OnEventHandlerRaised", BindingFlags.Instance | BindingFlags.NonPublic);
        var o = Activator.CreateInstance(typeof(EventToCommand));
        Delegate d = Delegate.CreateDelegate(info.EventHandlerType, o, handler);
        MethodInfo addHandler = info.GetAddMethod();
        object[] addHandlerArgs = { d };
        addHandler.Invoke(obj, addHandlerArgs);
    }

    private void OnEventHandlerRaised(object sender, EventArgs args)
    {
        // Is it a unique instance?
        Console.WriteLine(value);
    }

    Guid value = Guid.NewGuid();
    public EventToCommand()
    {
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羁拥 2024-10-26 19:13:39

由于这些是路由事件,我认为不会使用反射来注册事件。与数据绑定和依赖属性相同 - 它不是通过反射完成的。

Since those are routed events I don't think that reflection is used in order to register to the events. Same as in data binding and dependency properties - it's not done through reflection.

能怎样 2024-10-26 19:13:39

我在问题中提供的方法绝对是较慢的方法。更好的方法是使用下面的方法而不是使用invoke:

    Type objType = obj.GetType();
    var info = objType.GetEvent((string)args.NewValue);

    MethodInfo handler = typeof(EventToCommand).GetMethod("OnEventHandlerRaised", BindingFlags.Instance | BindingFlags.NonPublic);
    var o = Activator.CreateInstance(typeof(EventToCommand));
    Delegate d = Delegate.CreateDelegate(info.EventHandlerType, o, handler);
    info.AddEventHandler(obj, d);

上面的方法比使用Reflection的invoke要快很多。然后您可以通过 info.RemoveEventHandler(obj, d) 删除它。

The method I provided in my question is definitely the slower way to do it. The better way is to use the following and not use invoke:

    Type objType = obj.GetType();
    var info = objType.GetEvent((string)args.NewValue);

    MethodInfo handler = typeof(EventToCommand).GetMethod("OnEventHandlerRaised", BindingFlags.Instance | BindingFlags.NonPublic);
    var o = Activator.CreateInstance(typeof(EventToCommand));
    Delegate d = Delegate.CreateDelegate(info.EventHandlerType, o, handler);
    info.AddEventHandler(obj, d);

The above method is a lot faster than using Reflection's invoke. You can then remove it via info.RemoveEventHandler(obj, d).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文