WPF DataGridに動的に行と列を追加する方法

WPF DataGridに動的に行と列を追加する方法

WPFのDataGridにコード側から行と列を指定した数だけ追加する方法を紹介します。

それと各セルを直接触る方法も紹介します。セル内データに合わせて装飾を変更するのに役立つと思います。

ファイル解析なども捗りますね。

 

 

ヘッダー追加

for (int i = 0; i < 3; ++i)
{
    var column = new DataGridTextColumn();
    column.Header = $"列{i}";
    column.Binding = new Binding($"[{i}]");
    dataGrid.Columns.Add(column);
}

バインド指定の仕方がポイントです。指定するデータオブジェクトが読み込める形にしましょう。

 

 

行追加(列数指定)

var dataList = new ObservableCollection<List<string>>();

for (int i = 0; i < 10; ++i)
{
    // 適当なデータ作成
    List<string> data = new List<string>();
    data.Add("1");
    data.Add("2");
    data.Add("3");
    
    dataList.Add(data);
}

dataGrid.ItemsSource = dataList;

今回はList<string>型で10行追加しています。

データの中身は列数分追加しましょう。今回は3列なので直接1,2,3の文字を追加していますが、ここは動的に変更できるように組みましょう。

 

 

各セルを触る方法

// 各セルごとに対する処理 内容に応じた装飾など
private void EditDataGrid(object sender, RoutedEventArgs e)
{
    // 行列数
    int rowCount = dataGrid.Items.Count;
    int columnCount = dataGrid.Columns.Count;

    for (int i = 0; i < rowCount; ++i)
    {
        // データグリッドの行オブジェクトを取得します。
        var row = dataGrid.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow;
        // 行オブジェクトが取得できない場合
        if (row == null)
        {
            // 画面に表示されていないセルはnullとなる
            continue;
        }
        
        for (int j = 0; j < columnCount; ++j)
        {
            // データグリッドのセルオブジェクトを取得します。
            DataGridCell cell = (DataGridCell)dataGrid.Columns[j].GetCellContent(row).Parent;
            // データグリッドのセルオブジェクトが取得できない場合
            if (cell != null)
            {
                // 画面に表示されていないセルはnullとなる ここから各セルに対する処理

                // セルの子オブジェクトを取得
                var cellObject = dataGrid.Columns[j].GetCellContent(row);
                TextBlock tb = cellObject as TextBlock;

                //Console.WriteLine(tb.Text);
                cell.Background = Brushes.Chartreuse;
            }
        }
    }
}

行と列を総当りで指定して触るだけです。この方法は画面に表示されているセルしか取得できません。

なのでスクロールイベントと組み合わせて使うのが良いです。

 

private void ScrollEvent()
{
    Decorator child = VisualTreeHelper.GetChild(this.dataGrid, 0) as Decorator;
    ScrollViewer sc = child.Child as ScrollViewer;
    sc.ScrollChanged += new ScrollChangedEventHandler(EditDataGrid);
}

ItemsSourceを指定した直後に追加すると良いでしょう。

 

Xamlとcsコードは上げておいたので最小構成で起動するのが分かりやすいと思います。

 

この記事へのコメント

  1. 名前:suzuki 2020/04/24(金) 09:41:46返信する

    初めまして。
    現在WPFで開発をしている者です。

    DataGridで表を作成したあとに、数値が特定の範囲にあるセルの背景色を赤にする実装をしたいのですが、

    TextBlock tb = cellObject as TextBlock;

    //値が10以上のセルは赤くする
    if(tb.text >= 10)
    {
    cell.Background = Brushes.Red;
    }

    というようにやろうと思ったのですが、tb.Textが空のため、できませんでした。

    このようにセルの数値によってそのセルの背景色を変更したい場合、どの位置に条件式を記述すればよいでしょうか??

    何卒宜しくお願い致します。

  2. 名前:hyper_T 2020/04/24(金) 10:33:08返信する

    >>1
    書かれているコードや挿入場所は間違えていないと思います。
    サンプルのcellObjectの取得方法が間違えていたので修正しました。
    https://github.com/kame-chan/WPF/blob/master/GenDataGrid/MainWindow.xaml.cs#L104
     
    DataGridが作られた直後だとセルの中身が空なので、スクロールイベントに付けています。確認する際はウィンドウを小さくしてスクロールする必要があります。

  3. 名前:suzuki 2020/04/24(金) 14:00:07返信する

    >>2
    ご丁寧にありがとうございます。

    特定の値のセルのみを赤くすること自体はできたのですが、それはページを表示させたときでなくスクロールをしたタイミングなので、そこはこれから修正をしてみます。(本来はページを表示させた時点で赤くしたいため)

    本当にありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。URLを含むコメントは承認待ちになります。