DataGridCellInfoから、DataGridCellを探す。

DataGridCellInfoは、DataGridCellそのものではない(当たり前)。なので、
文字色や背景色、境界線(Border)等、Visual的な操作はできない。
DataGridCellInfoからDataGridCellを特定できないか?と調べたら、
「できることはできるけど、結構めんどくさい」
という結果になった。
手順的には…
①DataGridCellInfoのItemプロパティから、DataGridRowオブジェクトを探す。
②DataGridRowの子コントロールから、DataGridCellsPresenterオブジェクトを探す。
③DataGridCellsPresenterオブジェクトとDataGridCellInfoのColumnプロパティとで、DataGridCellオブジェクトを特定する。
箇条書きなのに、めんどくさいOrz。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace TawamureDays {

public static class DataGridExtender {

/// <summary>
/// (拡張メソッド)
/// 指定されたセル情報からDataGridCellオブジェクトを取得します。<br/>
/// </summary>
/// <param name="dataGrid">DataGridオブジェクト</param>
/// <param name="gridCellInfo">セル情報</param>
/// <returns>結果とオブジェクトのタプル(Item1:成否, Item2:DataGridCellオブジェクト)</returns>
public static Tuple<bool, DataGridCell> GetGridCellFromCellInfo(
this DataGrid dataGrid, DataGridCellInfo gridCellInfo) {

if (gridCellInfo == null || !gridCellInfo.IsValid || gridCellInfo.Item == null ||
dataGrid.Items.Count == 0) {
//パフォーマンス対策:そもそも探せる状況じゃないなら、終了
return Tuple.Create(false, null as DataGridCell);
}

//現在のセル(のItem)から現在の行(DataGridRow)を特定します。
var gridRow = (DataGridRow)dataGrid.ItemContainerGenerator.
ContainerFromItem(gridCellInfo.Item);

if (gridRow == null) {
return Tuple.Create(false, null as DataGridCell);
}

//列インデックスを取得します。
var colIndex = dataGrid.Columns.IndexOf(gridCellInfo.Column);

if (colIndex < 0) {
//列インデックスは、0以上の筈。
return Tuple.Create(false, null as DataGridCell);
}

//FirstOrDefaultで検索にヒットした最初のオブジェクトを取得します。
var cellsPresenter = gridRow.
FindVisualChildren<DataGridCellsPresenter>().FirstOrDefault();

if (cellsPresenter == null) {
return Tuple.Create(false, null as DataGridCell);
}

//DataGridCellを特定します。
var gridCell = cellsPresenter.ItemContainerGenerator.
ContainerFromIndex(colIndex) as DataGridCell;
return Tuple.Create(gridCell != null, gridCell);
}
}
}

色々な「if」を乗り越えて初めてDataGridCellオブジェクトにたどり着く。
使い方は、こんな感じ。

var dataGrid = dpObj as DataGrid;

if (dataGrid.CurrentCell != null) {
var dataGridCell = dataGrid.GetGridCellFromCellInfo(dataGrid.CurrentCell);

if (dataGridCell.Item1) {
....
}
}

これで、DataGridのCurrentCellオブジェクトから、DataGridCellオブジェクトを特定できる。
DataGrid向けの添付プロパティを実装する時に、裏側から色々操作したい時に重宝できる。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m