プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

WPFのDataGridのセルを取得する。

この記事は2019年05月08日に投稿しました。

f:id:paveway:20190914064630j:plain

目次

  1. はじめに
  2. WPFのDataGridのセルを取得する
  3. おわりに

1. はじめに

こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているWPFDataGridのセルを取得する方法についてです。

目次へ

2. WPFのDataGridのセルを取得する

WPFDataGridのセルを取得する方法ですが、以下のようにします。

実装例
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が表示された後でないと取得できないようです。
そのため例ではウィンドウがロードされた後にセルを取得するようにしています。

【Tech Stars Agent】

紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。

目次へ


私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。

また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。

EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688

目次へ