@@ -53,6 +53,16 @@ public ChartHoverHelper(ScottPlot.WPF.WpfPlot chart, string unit)
5353
5454 chart . MouseMove += OnMouseMove ;
5555 chart . MouseLeave += OnMouseLeave ;
56+
57+ /* Tab switching can leave the popup wedged: WPF unloads the parent TabItem
58+ without firing MouseLeave, so IsOpen stays true with a stale anchor.
59+ When the chart becomes visible again, OnMouseMove sets IsOpen = true
60+ but it is already true, so the popup never re-anchors and never shows.
61+ Force-close on every visibility/load transition so the next mouse move
62+ re-opens cleanly. */
63+ chart . IsVisibleChanged += OnChartVisibilityChanged ;
64+ chart . Unloaded += OnChartUnloaded ;
65+ chart . Loaded += OnChartLoaded ;
5666 }
5767
5868 public string Unit { get => _unit ; set => _unit = value ; }
@@ -61,11 +71,23 @@ public void Dispose()
6171 {
6272 _chart . MouseMove -= OnMouseMove ;
6373 _chart . MouseLeave -= OnMouseLeave ;
74+ _chart . IsVisibleChanged -= OnChartVisibilityChanged ;
75+ _chart . Unloaded -= OnChartUnloaded ;
76+ _chart . Loaded -= OnChartLoaded ;
6477 _popup . IsOpen = false ;
6578 _scatters . Clear ( ) ;
6679 _barPlots . Clear ( ) ;
6780 }
6881
82+ private void OnChartVisibilityChanged ( object sender , DependencyPropertyChangedEventArgs e ) =>
83+ _popup . IsOpen = false ;
84+
85+ private void OnChartUnloaded ( object sender , RoutedEventArgs e ) =>
86+ _popup . IsOpen = false ;
87+
88+ private void OnChartLoaded ( object sender , RoutedEventArgs e ) =>
89+ _popup . IsOpen = false ;
90+
6991 public void Clear ( )
7092 {
7193 _scatters . Clear ( ) ;
@@ -207,6 +229,11 @@ pick the series closest in Y (nearest line to cursor). */
207229 _text . Text = $ "{ bestLabel } \n { valueFormatted } { _unit } \n { time : HH:mm:ss} ";
208230 _popup . HorizontalOffset = pos . X + 15 ;
209231 _popup . VerticalOffset = pos . Y + 15 ;
232+ /* Toggle if already open so WPF re-evaluates the placement target.
233+ Without this, a popup that was IsOpen = true when its TabItem was
234+ unloaded stays "open" with a stale anchor and never appears on
235+ return — the assignment below is a no-op. */
236+ if ( _popup . IsOpen ) _popup . IsOpen = false ;
210237 _popup . IsOpen = true ;
211238 }
212239 else
0 commit comments