[Universal Windows App] - How to Add Handler to Windows Runtime Event Dynamiclly

 

Purpose: add a click event handler to all of the buttons in main page

 

#1 Iterate all of the button elements in the main page.

 private static bool Is<T>(UIElement obj) where T : UIElement

{

    return typeof(T).IsAssignableFrom(obj.GetType());

}

 

private static void FindElement<T>(Panel parent, ICollection<T> collection) where T : UIElement

{

    if (parent == null)

    {

        throw new ArgumentNullException("Augument parent can not be null!");

    }

    foreach (var ele in parent.Children)

    {

        if(Is<T>(ele))

        {

            collection.Add((T)ele);

        }else if(Is<Panel>(ele))

        {

            FindElement(ele as Panel, collection);

        }

    }

}

#2 Add handler to Windows Runtime Event

 private static void AddEventHandler(Object target, string name, Delegate handler)

{

    var runtimeEvent = target.GetType().GetRuntimeEvent("Click");

 

    Func<Delegate, EventRegistrationToken> add = (a) => {

        return (EventRegistrationToken)runtimeEvent.AddMethod.Invoke(target, new object[] { a });

    };

 

    Action<EventRegistrationToken> remove = (a) => {

        runtimeEvent.RemoveMethod.Invoke(runtimeEvent, new object[] { a });

    };

 

    WindowsRuntimeMarshal.AddEventHandler(add, remove, handler);

}

#3 Initialization

 List<Button> list = new List<Button>();

 

FindElement(this.Content as Panel, list);

 

var handlerMethodInfo = this.GetType().GetMethod("OnClick");

 

var delegateHandler = handlerMethodInfo.CreateDelegate(typeof(RoutedEventHandler), this);

 

foreach(var button in list)

{

    AddEventHandler(button, "Click", delegateHandler);

}