IEventHandler HandleEvent() not working?

I’ve been loving the new UIElements, but have stumbled into an issue with manually sending self-created events to a VisualElement with IEventHandler.HandleEvent(). I am most likely missing something in my logic/setup, but I have written a boiled-down, stupidifed version of my issue:

public class HandleEventExample : EditorWindow
{
    public void OnEnable()
    {
        var root = this.rootVisualElement;

        var button = new Button
        {
            text = "Button"
        };
        button.RegisterCallback<MouseUpEvent>(DoAThing);

        // I expect this to indirectly call 'DoAThing' through the callback
        button.HandleEvent(new MouseUpEvent());
        root.Add(button);
    }

    public void DoAThing(MouseUpEvent evt)
    {
        Debug.Log("Did a thing");
    }

    [MenuItem("Examples/Show Handle Event Example")]
    public static void ShowExample()
    {
        HandleEventExample window = GetWindow<HandleEventExample>();
    }
}

After pulling up a new instance through the menu item and attaching Visual Studio I can see the .HandleEvent() being called, but no breakpoint in ‘DoAThing’ code is caught through the callback. What gives?

I may be wildly misunderstanding the purpose of .HandleEvent and for that matter .SendEvent (which I also tried), but I have not seen any examples of these functions being used. Anyone got working examples?

Much thanks!

Hi!

This is how you should send an event to an element:

var engineEvent = new UnityEngine.Event()
// initialize the event with proper values
engineEvent.button = 1;
// ... more initialization

using (var mouseUp = MouseUpEvent.GetPooled(engineEvent))
{
    mouseUp.target = button;
    button.SendEvent(mouseUp);
}
  • Use an Event to initialize the UIElements event (we need to add an API to skip the UnityEngine.Event)
  • Take the event from a pool; this avoids allocation
  • Set the target of the event
  • Use SendEvent() to send the event into the system. This will do a full dispatch of the event in your VisualElement tree.
1 Like

Oh… so glad I asked :smile:. Works like a charm too, thanks!

Below is a working example as of 2019.1.0b3.

public class HandleEventExample : EditorWindow
{
    [MenuItem("Examples/Show Handle Event Example")]
    public static void ShowExample()
    {
        HandleEventExample window = GetWindow<HandleEventExample>();
    }

    public void OnEnable()
    {
        var root = this.rootVisualElement;

        var button = new Button { text = "Do a Thing" };
        button.RegisterCallback<MouseUpEvent>(DoAThing);

        // Found that use of some sort of third-party is required
        // in this contrived example...
        var buttonScheduler = button.schedule.Execute(() => SendMouseUpEventTo(button));
        buttonScheduler.ExecuteLater(0); // ms

        root.Add(button);
    }

    public void DoAThing(MouseUpEvent evt)
    {
        Debug.Log("Did a thing");
    }

    public void SendMouseUpEventTo(IEventHandler handler)
    {
        using (var mouseUp = MouseUpEvent.GetPooled(new Event()))
        {
            mouseUp.target = handler;
            handler.SendEvent(mouseUp);
        }
    }
}

Thanks again patrick, never created events before. Also fyi there’s a missing parameter/typo in your example at handler.SendEvent().

Glad it helped! I fixed my example, thanks :slight_smile: