質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

3回答

1160閲覧

datagridのItemSourceに、3次元のlistデータを渡す方法について

cesolution

総合スコア217

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2019/02/24 23:29

編集2019/02/25 05:24

前提・実現したいこと

現在、あるテキストデータを読み取って、WPF上にデータテーブルとして表示しようとしております。

現在の構成

datagridはxamlファイル側で、名前をdgexとして定義しています。

クラスの宣言とリストの宣言

public class ex { public string A { get; set; } public string B { get; set; } public List<String> C { get; set; } } List<ex> exl = new List<ex>();

xmlを読み取り、上記で宣言したex1に受け渡し→datagrid:dgexのItemsSourceに受け渡し

for(i=0;i<N;i++) { a1=xml.a; b1=xml.b; for(j=0;j<countN;j++) { cc.Add(xml.c[j]); } exl.Add(new ex {A=a1, B= b1, C=cc}); } dgex.ItemsSource = exl;

問題点

上記のように宣言すると、A,Bは正しく値が表示されますが、Cの部分が、(コレクション)となってしまいます。
xmlから読み取るcの数が予め決まっていれば、クラスの宣言をListではなく、c1、c2、、、ciといった形で、決まった数だけ宣言してやれば、上手く表示できるのですが、cの数が、読み取るxmlのタイプによって異なるため、上記のような試し方を行いましたが、上手くゆきませんでした。

以下のようなイメージの出力としたいと考えています。
イメージ説明

プログラミングに慣れておらず、様々なHP等から、データテーブルの表示方法の流れとして、クラス宣言→リスト宣言→datagridに渡すという流れしか知らないため、今回のような事例に対してはそもそものアプローチが間違っているのかもしれませんが、皆様のお知恵をお借りできれ大変助かります。

宜しくお願いいたします。

補足情報(FW/ツールのバージョンなど)

visual studio 2017

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hihijiji

2019/02/25 01:33

具体的にどのような表示にしたいのか、画像やXAMLなどで提示してください。
cesolution

2019/02/25 05:24

ご連絡ありがとうございます。表示のイメージを画像でアップいたしました。
guest

回答3

0

ベストアンサー

こんにちは!
リストCを単純に行としたいのであれば平坦化してやれば表示はできます。
もし、平坦化せずに1行にCのリストを表示させたければDataGridのDataGridTemplateColumnを使って
入れ子表示にすることもできますが、とりあえず前者について記載。
XMLの構造が質問内容から読み取れないので参考までに。

このような出力を想定した場合

ABC
A1B1C1-1
A1B1C1-2
A1B1C1-3
A1B2C2-1
A3B1C3-1
A3B1C3-2
```C#
public class ex
{
public string A { get; set; }
public string B { get; set; }
public String C { get; set; }
}
List<ex> exl = new List<ex>();
```
```C#
a1=xml.a;
b1=xml.b;
xml.c.select(x => new {A=a1, B= b1, C = x})
```

投稿2019/02/25 04:53

mikupedia

総合スコア159

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cesolution

2019/02/25 05:22

mikupedia様、私の言葉にできなかった部分を汲み取ってご提示いただきましてありがとうございます。 私のやりたいことは「平坦化せずに1行にCのリストを表示させたい」ということになるかと思いますが、ご提案いただきましたDataGridTemplateColumnを勉強して、検討してみたいと思います。素晴らしいご回答をありがとうございました。
Zuishin

2019/02/25 06:55

感心したんですよ。皮肉が混ざっているように感じられたとしたらそれは質問者に対するものです。
cesolution

2019/02/25 09:11

Zuishin様、分かりにくい質問の仕方で申し訳ございませんでした。 mikupedia様、重ね重ね御礼申し上げます。
guest

0

datagridのItemSourceに、3次元のlistデータを渡す方法について

3次元には違いないですが、動的なカラムの追加・不定個のカラム追加といったほうが通じやすいですね。

上記のように宣言すると、A,Bは正しく値が表示されますが、Cの部分が、(コレクション)となってしまいます。

AutoGenerateColumnsだとそのようになります。
DataGrid.AutoGenerateColumns プロパティ (System.Windows.Controls) | Microsoft Learn

そういう場合は列の自動作成をやめて、下記のようにインデクサでバインドするようにします。

xml

1<DataGrid x:Name="dgex" AutoGenerateColumns="False"> 2 <DataGrid.Columns> 3 <DataGridTextColumn Binding="{Binding A}" Header="A" /> 4 <DataGridTextColumn Binding="{Binding B}" Header="B" /> 5 <DataGridTextColumn Binding="{Binding C[0]}" Header="C-1" /> 6 </DataGrid.Columns> 7</DataGrid>

ただ最大個数が不明ということだとxamlに書けないので、実行時にC#コードで追加するしかないでしょう。
C#コードでカラムを追加しますが、基本的にはxamlで書くのと似たことなので、そんなに難しくないと思います。

バインドしているので編集も元のリストに反映されますが、値がないセル(Cがnull・個数が足りないところ)は入力しても値が入りません。
編集や行の追加がある場合は、そのあたりの手当てが必要です(回答コードを参照)

xml

1<Window 2 x:Class="Q176289.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450" 7 ThemeMode="System"> 8 <DataGrid x:Name="dgex" AutoGenerateColumns="False"> 9 <DataGrid.Columns> 10 <DataGridTextColumn Width="100" Binding="{Binding A}" Header="A" /> 11 <DataGridTextColumn Width="100" Binding="{Binding B}" Header="B" /> 12 <!-- C列はC#コードで追加 --> 13 <!--<DataGridTextColumn Width="100" Binding="{Binding C[0]}" Header="C-1" />--> 14 </DataGrid.Columns> 15 </DataGrid> 16</Window>

cs

1using System.Windows; 2using System.Windows.Controls; 3using System.Windows.Data; 4 5namespace Q176289; 6 7public class Ex 8{ 9 public string? A { get; set; } 10 public string? B { get; set; } 11 public List<string?>? C { get; set; } 12} 13 14public partial class MainWindow : Window 15{ 16 private List<Ex> exl; 17 private int maxCcount; 18 19 public MainWindow() 20 { 21 InitializeComponent(); 22 23 exl = [ 24 new() { A = "A1", B = "B1", }, 25 new() { A = "A2", B = "B2", C = ["C2-1", "C2-2",], }, 26 new() { A = "A3", B = "B3", C = ["C3-1", "C3-2", "C3-3",], }, 27 ]; 28 29 // 最大のCの個数 30 maxCcount = exl.Max(x => x.C?.Count ?? 0); 31 32 // C列カラム作成 33 for (var i = 0; i < maxCcount; i++) 34 { 35 var col = new DataGridTextColumn 36 { 37 Binding = new Binding($"C[{i}]"), 38 Header = $"C-{i + 1}", 39 Width = 100, 40 }; 41 dgex.Columns.Add(col); 42 } 43 dgex.ItemsSource = exl; 44 45 46 // 編集時の対策(編集しないならいらない) 47 foreach (var ex in exl) 48 { 49 // CがnllだったらmaxCcount個数分のリストを作成 50 ex.C ??= new(new string[maxCcount]); 51 // 個数が足りなかったら追加 52 if (ex.C.Count < maxCcount) ex.C.AddRange(new string[maxCcount - ex.C.Count]); 53 } 54 55 // 行の追加時の対策(追加しないならいらない) 56 dgex.AddingNewItem += DataGrid_AddingNewItem; 57 } 58 59 private void DataGrid_AddingNewItem(object? sender, AddingNewItemEventArgs e) 60 { 61 // 行の追加時にmaxCcount個数分のリストを用意 62 e.NewItem = new Ex { C = new(new string[maxCcount]), }; 63 } 64}

アプリ画像

投稿2024/11/24 15:11

TN8001

総合スコア10042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

DataTable を使うのが一番手軽かもしれません。

CSVファイルを読み込んでDataGridに表示

なお、リンク先はほとんど読んでいませんので、自分のしたいことと合致しているかどうか、情報が間違っていないかどうかは自分で確かめてみてください。

投稿2019/02/25 01:39

Zuishin

総合スコア28675

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cesolution

2019/02/25 05:23

ご提案ありがとうございます。ご紹介いただいたリンクも時間を見て勉強させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問