Event directives
Event directives are special attributes that can be used on template nodes handle events.
click
Sets the UI method that will be called when the node is clicked.
Directive name : event:click
The value must be the name of a method.
The method takes as first parameter a IUIEventArgs object. If the node bearing the directive is in a repeat node, the method must take a second parameter corresponding to the iterated element.
Example :
- Template:
<vertical-layout>
<text size="extralarge" event:click="HandleClick">
Title
</text>
<popover overlay-id="DetailsPopover">
<text>
Details
</text>
</popover>
</vertical-layout>
- HandleClick method:
- args : IUIEventArgs
ToggleOverlay(new ToggleOverlayOptions("DetailsPopover").WithTarget(args.CurrentTarget));
Arguments
The expected UI method take as first parameter an IUIEventArgs object that provides the following properties and methods:
object CurrentTarget: Gets the element to which the event handler has been attached.void StopPropagation(): Prevents the propagation of the current event.
keydown
Sets the UI method that will be called when a key is pressed while the focus is in the node or in one of its children.
Directive name : event:keydown
The value must be the name of a method.
The method takes as first parameter a IKeyboardEventArgs object. If the node bearing the directive is in a repeat node, the method must take a second parameter corresponding to the iterated element.
This event is equivalent to the keydown event in web development. It bubbles: put the directive on a container to react to the keys pressed in any of the fields it contains, such as Enter in a text box, and filter on args.Key in the method. The method is called for every key pressed, so it must return at once for the keys it does not handle. A button of the container receives its own Enter too, which also calls the method: when the container holds buttons, put the directive on the field itself instead.
Example :
- Template:
<horizontal-layout>
<textbox value="@Fields.Draft" event:keydown="HandleKeyDown" />
<button type="action" action-name="SendDraft" />
</horizontal-layout>
- HandleKeyDown method:
- args : IKeyboardEventArgs
if (args.Key != "Enter" || args.IsComposing)
{
return;
}
args.CommitActiveInput();
Methods.SendDraft();
In this example, pressing Enter in the text box sends the draft, like the button does.
Reading the value being typed
A field whose update mode is not immediate only gives its value to the view when it is committed, which happens after the keydown of the Enter key. Reading the value in the method would then give the previous one. Call args.CommitActiveInput() before reading it: the value being typed in the focused field is committed at once, as if the field had lost the focus. Do it after filtering the key, not before, so that the other keys do not commit anything.
Arguments
The expected UI method take as first parameter an IKeyboardEventArgs object that provides the same properties and methods as the click event arguments, and the following ones:
string Key: Gets the value of the key pressed, such as"Enter"or"Escape".bool AltKey: Gets a value indicating whether the Alt key was held down.bool CtrlKey: Gets a value indicating whether the Ctrl key was held down.bool IsComposing: Gets a value indicating whether the key is pressed during a composition of an input method editor (Enter confirming a candidate for instance). Ignore such a key in the method.bool MetaKey: Gets a value indicating whether the Meta key was held down.bool ShiftKey: Gets a value indicating whether the Shift key was held down.void CommitActiveInput(): Commits the value being typed in the focused field.
mouseenter
Sets the UI method that will be called when the mouse pointer enters the node.
Directive name : event:mouseenter
The value must be the name of a method.
The method takes as first parameter a IUIEventArgs object. If the node bearing the directive is in a repeat node, the method must take a second parameter corresponding to the iterated element.
This event is equivalent to the mouseenter event in web development. It is triggered when the mouse pointer enters the element's boundaries.
Example :
- Template:
<vertical-layout>
<text size="large" event:mouseenter="HandleMouseEnter">
Hover over me
</text>
</vertical-layout>
- HandleMouseEnter method:
- args : IUIEventArgs
// UIResources.Core.MouseEnterTitle (Scope=Frontend) => "Mouse Enter"
// UIResources.Core.MouseEnterMessage (Scope=Frontend) => "Mouse entered the element"
ShowToast(MessageType.Info, UIResources.Core.MouseEnterTitle, UIResources.Core.MouseEnterMessage);
Arguments
The expected UI method take as first parameter an IUIEventArgs object that provides the following properties and methods:
object CurrentTarget: Gets the element to which the event handler has been attached.void StopPropagation(): Prevents the propagation of the current event. Note: This method has no effect formouseenterevents.
mouseleave
Sets the UI method that will be called when the mouse pointer leaves the node.
Directive name : event:mouseleave
The value must be the name of a method.
The method takes as first parameter a IUIEventArgs object. If the node bearing the directive is in a repeat node, the method must take a second parameter corresponding to the iterated element.
This event is equivalent to the mouseleave event in web development. It is triggered when the mouse pointer leaves the element's boundaries.
Example :
- Template:
<vertical-layout>
<text size="large" event:mouseleave="HandleMouseLeave">
Mouse will leave me
</text>
</vertical-layout>
- HandleMouseLeave method:
- args : IUIEventArgs
// UIResources.Core.MouseLeaveTitle (Scope=Frontend) => "Mouse Leave"
// UIResources.Core.MouseLeaveMessage (Scope=Frontend) => "Mouse left the element"
ShowToast(MessageType.Info, UIResources.Core.MouseLeaveTitle, UIResources.Core.MouseLeaveMessage);
Arguments
The expected UI method take as first parameter an IUIEventArgs object that provides the following properties and methods:
object CurrentTarget: Gets the element to which the event handler has been attached.void StopPropagation(): Prevents the propagation of the current event. Note: This method has no effect formouseleaveevents.
Children and overlapping neighbors
The children of an element are part of it: moving the mouse pointer from an element onto one of its children does not trigger mouseleave, and moving it back does not trigger mouseenter again.
A neighbor is not part of the element, even when it is drawn over it, at the same place on the screen (for example two children of a canvas layout, or an element moved with style:translate). Moving the mouse pointer from the element onto such a neighbor triggers mouseleave on the element, although the pointer did not leave its area.
Rendering examples:
no
mouseleave on the bandmouseleave on the bandWhen an element reveals another one on hover, and the revealed element is a neighbor drawn over it, give both elements the same methods: moving from one to the other then triggers mouseleave on the first one and mouseenter on the second one, which set the same field back to the same value at once, without any visible change.
Example:
<canvas-layout layout:width="320" layout:height="160">
<vertical-layout layout:height="@Computeds.BandHeight" style:background="neutral-900/0.6" canvas:left="0" canvas:right="0" canvas:bottom="0"
event:mouseenter="ExpandBand" event:mouseleave="CollapseBand">
<text style:color="neutral-0">Bamboo watch</text>
</vertical-layout>
<!-- Drawn over the band, but not a child of it: it needs the same methods as the band -->
<button type="method" method-name="AddToCart" label="Add to cart" style:opacity="@Computeds.ButtonOpacity" canvas:right="8" canvas:bottom="8"
event:mouseenter="ExpandBand" event:mouseleave="CollapseBand" />
</canvas-layout>
In this example, ExpandBand and CollapseBand set the same field, from which BandHeight and ButtonOpacity are computed. Without the two directives on the button, moving the mouse pointer from the band onto the button would collapse the band and hide the button.
resize
Sets the UI method that will be called every time the size actually rendered for the node changes.
Directive name : event:resize
The value must be the name of a method.
The method takes as first parameter a IResizeEventArgs object. If the node bearing the directive is in a repeat node, the method must take a second parameter corresponding to the iterated element.
Unlike the other event directives, this one does not listen to a web event: the node is observed, and the method is called once the layout has been computed, then on every layout change. A size identical to the previous one is never reported twice.
Example :
- Template:
<vertical-layout event:resize="HandleContainerSizeChanged">
<datagrid />
</vertical-layout>
- HandleContainerSizeChanged method:
- args : IResizeEventArgs
Fields.ShowSideBySide = args.Size.Width > 900;
In this example, the HandleContainerSizeChanged method is called every time the vertical layout is resized, and decides whether the content should be displayed side by side.
Arguments
The expected UI method take as first parameter an IResizeEventArgs object that provides the following property:
IUIElementSize Size: Gets the size actually rendered for the node, carrying itsWidthandHeightin pixels asdecimalvalues.
The size is the node's border box: padding and border are included, margin is not.
To only store the size, use the layout:rendered-size directive instead. Both directives report the same size through the same mechanism, so a node uses one or the other, never both at once.
Warning
If the layout only needs to adapt to the viewport size and not to one specific container, prefer using @Viewport in UI template or Window.Current.Viewport in UI code.
See also
v-neos-event— theresizeevent in native UI views