Subscribe to parent events from custom UXML element

Hello,

Is it possible to define a custom UXML element that can be nested inside other elements to handle specific events? To be more concrete, I would like to connect a UI event to a command in my data source (similar to WPF interaction triggers), e.g. something like:

<Button>
   <MyCustomTrigger event-type-id="1">
      <Bindings>
         <DataBinding property="command" data-source-path="MyCommand" />
      </Bindings>
   </MyCustomTrigger>
</Button>

I succeeded in creating the custom trigger class, but now I don’t know how to subscribe to a specific event from the parent element (e.g., the button click) so that I can invoke the command’s Execute method accordingly. So far, I tried to override HandleEventTrickleDown / HandleEventBubbleUp without success.

I may misinterpret your intention, but you seem to be looking for a way to register the callback on the parent. If the hierarchy is stable and that you expect the parent to stay the same, I would register to the parent in the AttachToPanelEvent and remove the callback in a DetachFromPanelEvent. We you will be added to the panel you will be able to get the reference to your parent so you could simply :

parent.RegisterCallback<ClickEvent>(callback);

Let me know if this doesn’t answer your question. There may be a few thing that could help you in the manual page for the events and clickEvent pages.

1 Like

Hello Simon, thanks for the response! So in theory, something like this would work:

    [UxmlElement]
    public partial class EventTrigger : VisualElement
    {
        [UxmlAttribute]
        public ICommand Command;

        public EventTrigger()
        {
            RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
            RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel);
        }

        private void OnAttachToPanel(AttachToPanelEvent evt)
        {
            parent.RegisterCallback<ClickEvent>(OnClick);
        }

        private void OnDetachFromPanel(DetachFromPanelEvent evt)
        {
            parent.UnregisterCallback<ClickEvent>(OnClick);
        }

        private void OnClick(ClickEvent evt)
        {
            if (Command.CanExecute(evt))
            {
                Command.Execute(evt);
            }
        }
    }

The last issue is now that I get an exception because the ICommand cannot be serialized (which is actually not what I need). I only want to display the Command property in the builder so that (with right-click) I can define a DataBinding to the Command in my DataSource (i.e. the view model).

It sounds like you may want a UxmlObject
You can then serialize IConmand as a UxmlObject reference, similar to the ButtonBehaviour example in the docs: