3

短い: モデルを更新するために myModel.InvalidatePlot(true/false) を呼び出した後、OxyPlot マウス イベント ハンドラー (mySeries.MouseDown など) が一瞬キャッチされません。

詳細: OxyPlot ライブラリを型にはまらない方法で使用しています。グラフ全体を占める画像注釈を迅速に更新することで、バックグラウンドでのビデオの再生を模倣しています。これにより、マウス イベントを使用して画像にプロットできます。私の問題は、ビデオ/画像注釈の再生とマウス イベントが別々に機能することですが、「フレームの更新」中にマウス イベントが発生すると、それらの一部が失われます。私の考えでは、プロットが myModel.InvalidatePlot(true/false) で無効になると、モデルが更新されるまでマウス イベントは取得されません。

4

2 に答える 2

0

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 ソースコードで作成したパブリック メソッドを呼び出します。

 /// <summary>
 /// Sends mouse events from the overlaying grid to the PlotView. Forcing an Action.
 /// This was included due to an OxyPlot bug where the OnMouse... methods were not being called 
 /// when the plot was invalidated via InvalidatePlot(...)
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 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で、保護されたマウス イベント (OnMouseDown(MouseButtonEventArgs e)) を明示的に呼び出す関数 (ForceMouseDown(MouseButtonEventArgs e) など) を作成しました。

/// <summary>
/// Forces a call to Mouse handler. 
/// This was needed because the events were getting lost when the model was updating
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public void ForceMouseDown(MouseButtonEventArgs e){
    this.OnMouseDown(e);
}


/// <summary>
/// Invoked when an unhandled MouseDown attached event reaches an element in its route that is derived from this class. 
/// Implement this method to add class handling for this event.
/// </summary>
/// <param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> that contains the event data. 
/// This event data reports details about the mouse button that was pressed and the handled state.</param>
protected override void OnMouseDown(MouseButtonEventArgs e)
{
    base.OnMouseDown(e);
    if (e.Handled)
    {
        return;
    }

    this.Focus();
    this.CaptureMouse();

    // store the mouse down point, check it when mouse button is released to determine if the context menu should be shown
    this.mouseDownPoint = e.GetPosition(this).ToScreenPoint();

    e.Handled = this.ActualController.HandleMouseDown(this, e.ToMouseDownEventArgs(this));
}

この方法で問題を修正することで、OxyPlot が推奨する方法でマウス イベント ハンドラーを Plotview に追加できます。OnMouse#### イベントがまだ呼び出されているため、オーバーレイ グリッドによって明示的に呼び出されるようになりました。

于 2015-05-11T18:14:10.330 に答える