Skip to content

Commit 7410bc5

Browse files
Merge pull request erikdarlingdata#922 from erikdarlingdata/feature/916-correlated-crosshair-tooltip
Apply erikdarlingdata#916 popup-wedge fix to CorrelatedCrosshairManager
2 parents b9361f3 + 5b833ef commit 7410bc5

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

Dashboard/Helpers/CorrelatedCrosshairManager.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

Lite/Helpers/CorrelatedCrosshairManager.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)