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?
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.
Oh… so glad I asked . 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().