@@ -468,10 +468,21 @@ private void ShowToolTip(DependencyObject o, bool fromKeyboard)
468
468
}
469
469
470
470
_currentToolTip . SetValue ( OwnerProperty , o ) ;
471
- _currentToolTip . Opened += OnToolTipOpened ;
472
471
_currentToolTip . Closed += OnToolTipClosed ;
473
472
_currentToolTip . FromKeyboard = fromKeyboard ;
474
- _currentToolTip . IsOpen = true ;
473
+
474
+ if ( ! _currentToolTip . IsOpen )
475
+ {
476
+ // open the tooltip, and finish the initialization when its popup window is available.
477
+ _currentToolTip . Opened += OnToolTipOpened ;
478
+ _currentToolTip . IsOpen = true ;
479
+ }
480
+ else
481
+ {
482
+ // If the tooltip is already open, initialize it now. This only happens when the
483
+ // app manages the tooltip directly.
484
+ SetSafeArea ( _currentToolTip ) ;
485
+ }
475
486
476
487
CurrentToolTipTimer = new DispatcherTimer ( DispatcherPriority . Normal ) ;
477
488
CurrentToolTipTimer . Interval = TimeSpan . FromMilliseconds ( ToolTipService . GetShowDuration ( o ) ) ;
@@ -632,6 +643,7 @@ private void ClearServiceProperties(ToolTip tooltip)
632
643
{
633
644
tooltip . ClearValue ( OwnerProperty ) ;
634
645
tooltip . FromKeyboard = false ;
646
+ tooltip . Closed -= OnToolTipClosed ;
635
647
636
648
if ( ( bool ) tooltip . GetValue ( ServiceOwnedProperty ) )
637
649
{
@@ -727,8 +739,27 @@ private void OnToolTipOpened(object sender, EventArgs e)
727
739
private void OnToolTipClosed ( object sender , EventArgs e )
728
740
{
729
741
ToolTip toolTip = ( ToolTip ) sender ;
730
- toolTip . Closed -= OnToolTipClosed ;
731
- ClearServiceProperties ( toolTip ) ;
742
+ if ( toolTip != CurrentToolTip )
743
+ {
744
+ // if we manage the tooltip (the normal case), the current tooltip closes via
745
+ // 1. DismissCurrentToolTip sets _currentToolTip=null and calls CloseToolTip
746
+ // 2. CloseToolTip sets toolTip.IsOpen=false, and returns
747
+ // 3. Asynchronously, the tooltip raises the Closed event (after popup animations have run)
748
+ // 4. our event handler OnToolTipClosed gets here
749
+ // It's now time to do the final cleanup, which includes removing this event handler.
750
+ ClearServiceProperties ( toolTip ) ;
751
+ }
752
+ else
753
+ {
754
+ // we get here if the app closes the current tooltip or its popup directly.
755
+ // Do nothing (i.e. ignore the event). This leaves the service properties in place -
756
+ // eventually DismissCurrentToolTip will call CloseToolTip, which needs them
757
+ // (in particular the Owner property). When that happens, either
758
+ // a. tooltip.IsOpen==false. CloseToolTip clears the service properties immediately.
759
+ // b. tooltip.IsOpen==true. (This can happen if the app re-opens the tooltip directly.)
760
+ // CloseToolTip proceeds as in step 2 of the normal case.
761
+ // Either way, the final cleanup happens.
762
+ }
732
763
}
733
764
734
765
// The previous tooltip hasn't closed and we are trying to open a new one
0 commit comments