-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New ToolTipClosing, ToolTipOpening attached events and ToolTip.Opened, ToolTip.Closed #15493
Conversation
You can test this PR using the following package version. |
In case of custom drawn controls, tooltip content may depend on the position of the cursor thus it would be very useful to have a location of the pointer in ToolTipOpeningEvent that is causing the tooltip to show up if it is possible |
Is it a technical limitation? I can see uses in preventing tooltips from closing. |
Should we unify the API between all popup-like controls here? Having all necessary events ( |
src/Avalonia.Controls/ToolTip.cs
Outdated
if (isOpen) | ||
{ | ||
var args = new RoutedEventArgs(ToolTipOpeningEvent); | ||
control.RaiseEvent(args); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll let @grokys comment on this, but I'm a bit worried of having such side effects in coercion methods, potentially leading to reentrancy or other hard to debug problems. Coercion methods are called in the middle of setting an EffectiveValue
, and I don't think this code currently handle reentrancy. (For example, PropertyChanged
isn't called until all the internal effective value bookkeeping is done to avoid issues.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, didn't think about reentrancy. It's technically possible to change IsOpen value inside.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also possible for the events to be raised when the value isn't changing. Aside from any internal coercion calls, the user can do this at any time:
myControl.CoerceValue(ToolTip.IsOpenProperty);
ToolTip.IsOpenChanged
is the right place for this code. It's a bit weird that IsOpen
will be true when ToolTipOpening
is raised, but the event name makes it very clear what's going on.
I'm a big fan of unifying APIs everywhere it's possible. This is a great place to do it IMO. Also note that |
@maxkatz6 The update works well. I was able to dynamically update a tooltip before it displayed. I agree that having a consistent API for the I'm also usually a fan of using something like |
Note that this exact topic was discussed for Expander here: #9979 (comment). The agreement was to add Just keep in mind Avalonia has these cancel event args already and 3rd party libraries should ideally use them as well. |
src/Avalonia.Controls/ToolTip.cs
Outdated
/// ToolTipOpening will not be raised if the value of ToolTip is null or otherwise unset. Do not deliberately set ToolTip to null while a tooltip is open or opening; this will not have the effect of closing the tooltip, and will instead create an undesirable visual artifact in the UI. | ||
/// </remarks> | ||
public static readonly RoutedEvent ToolTipOpeningEvent = | ||
RoutedEvent.Register<ToolTip, RoutedEventArgs>("ToolTipOpening", RoutingStrategies.Direct); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed new events here should follow existing conventions and use CancelRoutedEventArgs
. This follows Expander which itself was based on what Flyout did (although flyout isn't API symmetric and doesn't allow cancelling an open).
@cla-avalonia recheck |
|
@cla-avalonia agree |
…sing # Conflicts: # tests/Avalonia.Controls.UnitTests/ToolTipTests.cs
Updated PR:
Note, Closing event is still not cancellable. If necessary, it can be implemented later. |
You can test this PR using the following package version. |
@maxkatz6 Thanks, I tried the PR build and it does what we needed for the tooltip opening notification. |
You can test this PR using the following package version. |
What does the pull request do?
Behavior is ported from WPF, but implementation is different, just like our ToolTip API is already quite different. Most of this decisions were made for consistency with the rest of the framework.
Common:
Different:
To raise Opening/Closing events, I used IsOpen.Coerse callback, which is also handy to cancel tooltip opening. In WPF these events were only usable via ToolTipService, and handled there. In general, in Avalonia tooltip is completely usable without ToolTipService, so these events should as well.
Checklist
Fixed issues
Fixes #15232