Posted at

WPF OxyPlotをDataGridと連動させる

More than 1 year has passed since last update.

グラフが書けるライブラリ「OxyPlot」でトラッカーを動かした時にDataGridも連動させたかったのでやってみた

こんな感じで動いてくれる

DataGridLinkeOxyPlotSample.gif

※OxyPlotについてはドキュメントみればなんとなくわかると思うのでここでは使い方とかは解説しない

需要があればざっくりの使い方の記事書くかも


やりかた

前提として、同じデータのコレクションがOxyPlotとDataGirdにバインドされていること

    public class PointData

{
public double _X{ get; set; }
public double _YA { get; set; }
public double _YB{ get; set; }
public double _YC{ get; set; }
public double _YD{ get; set; }
public double _YE{ get; set; }
public double _YF{ get; set; }
}

サンプルデータはこんな感じにしている

そんで

    public class OxyPlot_Behavior : Behavior<Plot>

{
#region targetDataGridプロパティ
public DataGrid targetDataGrid
{
get { return (DataGrid)GetValue(targetDataGridProperty); }
set { SetValue(targetDataGridProperty, value); }
}
// Using a DependencyProperty as the backing store for targetDataGrid. This enables animation, styling, binding, etc...
public static readonly DependencyProperty targetDataGridProperty =
DependencyProperty.Register("targetDataGrid", typeof(DataGrid), typeof(OxyPlot_Behavior), new PropertyMetadata(null));
#endregion

protected override void OnAttached()
{
AssociatedObject.ActualModel.TrackerChanged += ActualModel_TrackerChanged;
}

protected override void OnDetaching()
{
AssociatedObject.ActualModel.TrackerChanged -= ActualModel_TrackerChanged;
}

private void ActualModel_TrackerChanged(object sender, TrackerEventArgs e)
{
if (e.HitResult == null) return;
var res = e.HitResult.Item as PointData;
targetDataGrid.Focus();
targetDataGrid.SelectedIndex = targetDataGrid.Items.IndexOf(res);
targetDataGrid.CurrentCell = new DataGridCellInfo(res, targetDataGrid.Columns[0]);
}
}

こんな感じのBehaviorを作ってDataGridをバインドするだけ

ポイントは、

AssociatedObject.ActualModelのTrackerChangedイベントに処理を書くこと

実際にやってることはイベントから取れるItemの行をDataGrid内から探して、それを選択して移動してるだけ

Viewはこんな感じでバインドする

<i:Interaction.Behaviors>

<be:OxyPlot_Behavior targetDataGrid="{Binding ElementName=DataGrid, Mode=OneWay}"/>
</i:Interaction.Behaviors>