@@ -74,9 +74,28 @@ public void AddLane(ScottPlot.WPF.WpfPlot chart, string label, string unit)
7474 chart . MouseMove += ( s , e ) => OnMouseMove ( lane , e ) ;
7575 chart . MouseLeave += ( s , e ) => OnMouseLeave ( ) ;
7676
77+ /* Tab switching can leave the popup wedged: WPF unloads the parent TabItem
78+ without firing MouseLeave, so IsOpen stays true with a stale anchor.
79+ When a chart becomes visible again, OnMouseMove sets IsOpen = true but
80+ it is already true, so the popup never re-anchors. Force-close on every
81+ visibility/load transition for any lane so the next mouse move re-opens
82+ cleanly. */
83+ chart . IsVisibleChanged += OnLaneVisibilityChanged ;
84+ chart . Unloaded += OnLaneUnloaded ;
85+ chart . Loaded += OnLaneLoaded ;
86+
7787 _lanes . Add ( lane ) ;
7888 }
7989
90+ private void OnLaneVisibilityChanged ( object sender , DependencyPropertyChangedEventArgs e ) =>
91+ _tooltip . IsOpen = false ;
92+
93+ private void OnLaneUnloaded ( object sender , RoutedEventArgs e ) =>
94+ _tooltip . IsOpen = false ;
95+
96+ private void OnLaneLoaded ( object sender , RoutedEventArgs e ) =>
97+ _tooltip . IsOpen = false ;
98+
8099 /// <summary>
81100 /// Sets the expected baseline range for a lane (upper/lower bounds).
82101 /// Values outside this range get ▲/▼ indicators in the tooltip.
@@ -287,6 +306,11 @@ private void OnMouseMove(LaneInfo sourceLane, MouseEventArgs e)
287306 _tooltip . PlacementTarget = sourceLane . Chart ;
288307 _tooltip . HorizontalOffset = pos . X + 15 ;
289308 _tooltip . VerticalOffset = pos . Y + 15 ;
309+ /* Toggle if already open so WPF re-evaluates the placement target.
310+ Without this, a popup that was IsOpen = true when its TabItem was
311+ unloaded stays "open" with a stale anchor and never appears on
312+ return — the assignment below is a no-op. */
313+ if ( _tooltip . IsOpen ) _tooltip . IsOpen = false ;
290314 _tooltip . IsOpen = true ;
291315 }
292316
@@ -373,6 +397,9 @@ public void Dispose()
373397 _tooltip . IsOpen = false ;
374398 foreach ( var lane in _lanes )
375399 {
400+ lane . Chart . IsVisibleChanged -= OnLaneVisibilityChanged ;
401+ lane . Chart . Unloaded -= OnLaneUnloaded ;
402+ lane . Chart . Loaded -= OnLaneLoaded ;
376403 lane . Series . Clear ( ) ;
377404 lane . VLine = null ;
378405 }
0 commit comments