Как System.Windows.Interactivity.EventTrigger.EventName эффективно работает с отражением или без него? - PullRequest
0 голосов
/ 01 марта 2011

Я вижу, что System.Windows.Interactivity.EventTrigger.EventName принимает строку. Кроме того, я полагаю, что они должны подключиться к этому событию с помощью отражения.

Но у отражения немного плохое имя, особенно с производительностью, поэтому есть проблемы с производительностью System.Windows.Interactivity.EventTrigger . Итак, является ли приведенный ниже код наиболее эффективным способом подключения к событию, а SDK Expression Blend делает что-то особенное?

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()
    {
    }
}

Ответы [ 2 ]

0 голосов
/ 02 марта 2011

Метод, который я указал в моем вопросе, определенно медленнее.Лучший способ - использовать следующее и не использовать 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);

Вышеуказанный метод намного быстрее, чем использование invoke Reflection.Затем вы можете удалить его с помощью info.RemoveEventHandler (obj, d).

0 голосов
/ 01 марта 2011

Поскольку это перенаправленные события, я не думаю, что отражение используется для регистрации в событиях.То же, что и в свойствах привязки данных и зависимостей - это не делается с помощью отражения.

...