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: