この記事は2019年05月08日に投稿しました。
目次
リンク
1. はじめに
こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているWPFのDataGridのセルを取得する方法についてです。
2. WPFのDataGridのセルを取得する
WPFのDataGridのセルを取得する方法ですが、以下のようにします。
実装例
MainWindow.xaml
<Window x:Class="WPFGetDataGridCell.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WPFGetDataGridCell" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded"> <Grid> <DataGrid AutoGenerateColumns="false" Name="dataGrid1" ItemsSource="{Binding}"/> </Grid> </Window>
MainWindow.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPFGetDataGridCell { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { /** * @brief コンストラクタ */ public MainWindow() { InitializeComponent(); // データグリッドに列を3つ設定します。 for (int i = 0; i < 3; ++i) { // 追加する列はテキストカラムとしてます。 var column = new DataGridTextColumn(); column.Header = $"列{i}"; column.Binding = new Binding($"[{i}]"); dataGrid1.Columns.Add(column); } // データグリッドに行を4つ設定します。 var row1 = new string[] { "データ1-1", "データ1-2", "データ1-3" }; var row2 = new string[] { "データ2-1", "データ2-2", "データ2-3" }; var row3 = new string[] { "データ3-1", "データ3-2", "データ3-3" }; var row4 = new string[] { "データ4-1", "データ4-2", "データ4-3" }; var row5 = new string[] { "データ5-1", "データ5-2", "データ5-3" }; var rows = new List<object>(); rows.Add(row1); rows.Add(row2); rows.Add(row3); rows.Add(row4); rows.Add(row5); dataGrid1.ItemsSource = rows; } /** * @brief ウィンドウがロードされた後呼び出されます。 * * @param [in] sender ウィンドウ * @param [in] e イベント */ private void Window_Loaded(object sender, RoutedEventArgs e) { // データグリッドのセルの取得は、データグリッドが表示された後に行います。 // データグリッドの行数を取得します。 var rowCount = dataGrid1.Items.Count; // データグリッドの行数分繰り返します。 for (int i = 0; i < rowCount; ++i) { // データグリッドの行オブジェクトを取得します。 var row = dataGrid1.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow; // 行オブジェクトが取得できない場合 if (row == null) { // 対象の行が表示されていない場合、行オブジェクトが取得できないため // 対象の行が表示されるようスクロールします。 dataGrid1.UpdateLayout(); dataGrid1.ScrollIntoView(dataGrid1.Items[i]); // 再度、行オブジェクトを取得します。 row = dataGrid1.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow; } // データグリッドの列数を取得します。 var columnCount = dataGrid1.Columns.Count; // データグリッドの列数分繰り返します。 for (int j = 0; j < columnCount; ++j) { // データグリッドのセルオブジェクトを取得します。 var cell = dataGrid1.Columns[j].GetCellContent(row); // データグリッドのセルオブジェクトが取得できない場合 if (cell == null) { // 対象のセルが表示されていない場合、セルオブジェクトが取得できないため // 対象のセルが表示されるようスクロールします。 dataGrid1.UpdateLayout(); dataGrid1.ScrollIntoView(dataGrid1.Columns[j]); // 再度、セルオブジェクトを取得します。 cell = dataGrid1.Columns[j].GetCellContent(row); } // 以降の処理は、取得したセルの種類により処理します。 // 今回取得したセルはテキストブロックのため、テキストブロックにキャストします。 var textBlock = cell as TextBlock; Console.WriteLine(textBlock.Text); } } } } }
3. おわりに
DataGridのセルにコードでToolTipを設定しようとしましたが、セルは簡単には取得できませんでした。
またセルはDataGridが表示された後でないと取得できないようです。
そのため例ではウィンドウがロードされた後にセルを取得するようにしています。
リンク
紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。
私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリやウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。
また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。
EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688