我发现InvalidatePlot导致了一个问题,即鼠标按钮事件(例如OnMouseDown(MouseButtonEventArgs e))从未被PlotView捕获。为了解决这个问题,我使用了另一个WPF对象来捕获鼠标事件并强制调用我的PlotView的鼠标处理方法:
1)我在另一个ZIndex级别上添加了一个WPF网格,并附加了函数到鼠标事件(MouseDown,MouseWheel等):
<Grid x:Name="Grid_MouseCatcher"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Panel.ZIndex="2"
MouseDown="Grid_MouseCatcher_MouseDown"
MouseEnter="Grid_MouseCatcher_MouseEnter"
MouseLeave="Grid_MouseCatcher_MouseLeave"
MouseMove="Grid_MouseCatcher_MouseMove"
MouseUp="Grid_MouseCatcher_MouseUp"
MouseWheel="Grid_MouseCatcher_MouseWheel"
Opacity="0.0"
PreviewMouseMove="SetFocusToOxyPlot" />
<oxy:PlotView x:Name="PlotView"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Panel.ZIndex="1"
Model="{Binding PlotModel}" />
2) 网格处理的每个事件都会调用我在 OxyPlot 源代码中创建的公共方法:
private void Grid_MouseCatcher_MouseDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("MouseCatcher - Down: " + e.GetPosition(Grid_MouseCatcher).X + " " + e.GetPosition(Grid_MouseCatcher).Y);
PlotView.ForceMouseDown(e);
}
3)在源代码文件OxyPlot.Wpf\PlotBase.Events.cs中,我创建了函数(例如ForceMouseDown(MouseButtonEventArgs e)),它显式调用受保护的鼠标事件(OnMouseDown(MouseButtonEventArgs e))
public void ForceMouseDown(MouseButtonEventArgs e){
this.OnMouseDown(e);
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
if (e.Handled)
{
return;
}
this.Focus();
this.CaptureMouse();
this.mouseDownPoint = e.GetPosition(this).ToScreenPoint();
e.Handled = this.ActualController.HandleMouseDown(this, e.ToMouseDownEventArgs(this));
}
通过这种方式修复问题,我仍然可以按照OxyPlot的建议为我的Plotview添加鼠标事件处理程序,因为它们的OnMouse####事件仍然被调用,只是现在由覆盖网格显式调用。