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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

1回答

669閲覧

コンボボックス付きの表から選択した値を抽出して保存したい。

AAAAAAAAAAAAAA

総合スコア4

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

1グッド

0クリップ

投稿2023/07/12 01:51

実現したいこと

C#のDatagridを使用したコンボボックス付きの表からデータを取り出したい。
ここに実現したいことを箇条書きで書いてください。

  • コンボボックスを選ぶとそれに応じてテキストファイルから読み込んだ項目の表が作成される。
  • その一部はコンボボックス付きの表となっている。
  • そのコンボボックスを選択し終えてボタンを押すと、コンボボックスで選んだ項目をリストとして保存した後、表を全消去して再度コンボボックスなしの表として作り直すというプログラムを作成しています。
  • 「コンボボックスで選んだ項目をリストとして保存」の部分が上手くいかずに困っています。

前提

・言語:C#
・OS:Windows 10
・開発環境:visual studio 2022(.NET framework4.8)
あるソフトのスクリプト機能で動くdllを作成しています。
実行してもエラーは出ませんが、コンボボックスの列で選んだ項目をリストに保存したいのに、別の列の値が保存されてしまいます。
コンボボックス付きの列は列番号がないのか選択できていないようです。

該当のソースコード

C#

1private void site_tb_Combo_SelectionChanged(object sender, SelectionChangedEventArgs e) 2 { 3    〈省略〉 4 5 D_table.ItemsSource = null; 6 // 既存の列をクリア 7 D_table.Columns.Clear(); 8 9 // データソースとしてDataTableを使用 10 DataTable dataTable = new DataTable(); 11 dataTable.Columns.Add("評価項目", typeof(string)); 12 dataTable.Columns.Add("評価指標", typeof(string)); 13 dataTable.Columns.Add("許容値1", typeof(string)); 14 dataTable.Columns.Add("許容値2", typeof(string)); 15 dataTable.Columns.Add("判定", typeof(string)); 16 17 // データを追加 18 for (int i = 0; i < structureList.Count; i++) 19 { 20 dataTable.Rows.Add(structureList[i], indexList[i], constraints1List[i], constraints2List[i]); 21 } 22 23 // DataGridにデータソースを設定 24 D_table.ItemsSource = dataTable.DefaultView; 25 26 // コンボボックス付きの列(使用項目)を作成 27 DataGridTemplateColumn columnC = new DataGridTemplateColumn(); 28 columnC.Header = "使用項目"; // 列のヘッダーを設定 29 30 // ドロップダウンメニューの編集用テンプレートを作成 31 FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ComboBox)); 32 factory.SetValue(ComboBox.ItemsSourceProperty, Structure_List); 33 factory.SetValue(ComboBox.SelectedValueProperty, new Binding($"[{dataTable.Columns.Count}]")); 34 factory.SetValue(ComboBox.IsEditableProperty, true); 35 36 DataTemplate cellTemplate = new DataTemplate(); 37 cellTemplate.VisualTree = factory; 38 columnC.CellEditingTemplate = cellTemplate; 39 columnC.CellTemplate = cellTemplate; 40 41 // DataGridの表の2列目にコンボボックス付きの列(使用項目)を追加 42 D_table.Columns.Insert(1, columnC); 43 44 // 列インデックスを特定(列番号が不明なので特定する必要がある?) 45 int structureNameColumnIndex = -1; 46 47 for (int i = 0; i < D_table.Columns.Count; i++) 48 { 49 if (D_table.Columns[i].Header.ToString() == "使用項目") 50 { 51 structureNameColumnIndex = i; 52 break; 53 } 54 } 55    // グローバル変数に保存 56 GlobalVariables2.structureNameColumnIndex = structureNameColumnIndex; 57 58 } 59 60 61 62 private void button_Click(object sender, RoutedEventArgs e) 63 { 64    // グローバル変数から必要なものを受け取る 65 List<string> structureList = GlobalVariables2.structureList; 66 List<string> indexList = GlobalVariables2.indexList; 67 List<string> constraints1List = GlobalVariables2.constraints1List; 68 List<string> constraints2List = GlobalVariables2.constraints2List; 69 int structureNameColumnIndex = GlobalVariables2.structureNameColumnIndex; 70 71 72    //表中のコンボボックスの列で選択された項目をリストとして保存する(ここが上手くいかない) 73 List<string> selected_structure = new List<string>(); 74 selected_structure.Clear(); 75 foreach (DataRowView rowView in D_table.ItemsSource) 76 { 77 DataRow row = rowView.Row; 78 string selectedStructure = row[structureNameColumnIndex].ToString();// 使用項目の列から値を取得 79 selected_structure.Add(selectedStructure); // リストに追加 80 } 81 82 D_table.ItemsSource = null; 83 // 既存の列をクリア 84 D_table.Columns.Clear(); 85 86 // データソースとしてDataTableを使用 87 DataTable dataTable = new DataTable(); 88 dataTable.Columns.Add("評価項目", typeof(string)); 89 dataTable.Columns.Add("使用項目", typeof(string)); 90 dataTable.Columns.Add("評価指標", typeof(string)); 91 dataTable.Columns.Add("制約1", typeof(string)); 92 dataTable.Columns.Add("制約2", typeof(string)); 93 dataTable.Columns.Add("判定", typeof(string)); 94 95 // データを追加 96 for (int i = 0; i < structureList.Count; i++) 97 { 98 dataTable.Rows.Add(structureList[i], selected_structure[i], indexList[i], constraints1List[i], constraints2List[i]); 99 } 100 101 // DataGridにデータソースを設定 102 D_table.ItemsSource = dataTable.DefaultView; 103 104 105 106 }

試したこと

C#

1 D_table.Columns.Insert(1, columnC);

上記のようにコンボボックス付きの列を後から追加しているので列番号がおかしくなっていると考え、
以下のように列番号を探してみましたがこの列番号で指定してもダメでした。
コンボボックス付きの使用項目の列で選択された値を保存する方法が知りたいです。

C#

1 int structureNameColumnIndex = -1; 2 3 // 列インデックスを特定 4 for (int i = 0; i < D_table.Columns.Count; i++) 5 { 6 if (D_table.Columns[i].Header.ToString() == "使用項目") 7 { 8 structureNameColumnIndex = i; 9 break; 10 } 11 }

疑問点

他の疑問点として、発生する表はリストよりも1つ大きい大きさになります。
リストに10個格納されていれば11行の表が発生し、11行目は空白になります。
11行目がどうしても消えないのですが消す方法はありますでしょうか?

TN8001👍を押しています

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

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

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

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

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

YAmaGNZ

2023/07/12 02:41

保存しようとしているD_table.ItemsSource(データテーブル)には追加した列(コンボボックスの列)はないのではないですか? 列を追加したのはあくまでDataGridであってItemsSourceに設定してあるDataTableには追加してないのではないでしょうか。 >リストに10個格納されていれば11行の表が発生し、11行目は空白になります 新規追加行はどうなっているのですか?
AAAAAAAAAAAAAA

2023/07/12 23:30

D_tableに「D_table.Columns.Insert(1, columnC);」で入れているのでDataTableに入っているのではないかと思ったのですが入っていないから呼び出せないのかもしれません。 リストについては何のリストを入れても空白が1つ多く追加されます。
guest

回答1

0

ベストアンサー

ただでさえFrameworkElementFactoryはややこしいので、もっとシンプルに行きましょう。

  1. 最初からDataTableに「使用項目」を入れておく
  2. 「使用項目」のDataGridColumnだけ入れ替える
  3. ボタンを押したらDataGridColumnを元に戻す

他の疑問点として、発生する表はリストよりも1つ大きい大きさになります。

D_table.CanUserAddRows = false;をどこかに入れてください(1回設定すれば十分です)
DataGrid.CanUserAddRows プロパティ (System.Windows.Controls) | Microsoft Learn

cs

1private void site_tb_Combo_SelectionChanged(object sender, SelectionChangedEventArgs e) 2{ 3 var structureList = GlobalVariables2.structureList; 4 var indexList = GlobalVariables2.indexList; 5 var constraints1List = GlobalVariables2.constraints1List; 6 var constraints2List = GlobalVariables2.constraints2List; 7 8 D_table.ItemsSource = null; 9 D_table.Columns.Clear(); 10 11 var dataTable = new DataTable(); 12 dataTable.Columns.Add("評価項目", typeof(string)); 13 dataTable.Columns.Add("使用項目", typeof(string)); // 最初から入れておく 14 dataTable.Columns.Add("評価指標", typeof(string)); 15 dataTable.Columns.Add("許容値1", typeof(string)); 16 dataTable.Columns.Add("許容値2", typeof(string)); 17 dataTable.Columns.Add("判定", typeof(string)); 18 19 for (var i = 0; i < structureList.Count; i++) 20 { 21 dataTable.Rows.Add(structureList[i], null, indexList[i], 22 constraints1List[i], constraints2List[i], null); 23 } 24 D_table.ItemsSource = dataTable.DefaultView; 25 26 // デフォルトのカラムを取っておく 27 selectedStructureColumn = D_table.Columns[1]; 28 29 30 var factory = new FrameworkElementFactory(typeof(ComboBox)); 31 factory.SetValue(ComboBox.ItemsSourceProperty, structureList); 32 factory.SetValue(ComboBox.IsEditableProperty, true); 33 var binding = new Binding("[1]") // 「使用項目」0始まりの2個目 34 { 35 // CellTemplateにComboBoxを入れる場合は必須 36 UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, 37 }; 38 39 // SetValueでも同じだがSetBindingのほうが意図が明確 40 factory.SetBinding(ComboBox.SelectedValueProperty, binding); 41 42 var column = new DataGridTemplateColumn 43 { 44 CellTemplate = new DataTemplate { VisualTree = factory, }, 45 Header = "使用項目", 46 }; 47 48 // ComboBoxに入れ替え 49 D_table.Columns[1] = column; 50} 51 52// デフォルトで作成された「使用項目」カラム 53private DataGridColumn selectedStructureColumn; 54 55private void button_Click(object sender, RoutedEventArgs e) 56{ 57 // デフォルトのカラムに戻す 58 D_table.Columns[1] = selectedStructureColumn; 59 60 // 別にカラムを作り直してもいいけどさ。DataTableまで作り直す必要はない! 61 //var view = D_table.ItemsSource; 62 //D_table.ItemsSource = null; 63 //D_table.Columns.Clear(); 64 //D_table.ItemsSource = view; 65}

ボタンを先に押すと(カラムがないので)当然エラー(ArgumentOutOfRangeException)になります。

投稿2023/07/12 08:55

TN8001

総合スコア10022

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

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

AAAAAAAAAAAAAA

2023/07/12 23:46

回答の通りにプログラムに組み込んてみたら上手くいきました!! ありがとうございます。 ここからさらに機能を追加する予定なのでまたわからないことがありましたら質問させていただくかもしれません。 よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問