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

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

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

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

Visual Studio

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

Q&A

解決済

2回答

1803閲覧

c#: コンボボックス選択に応じた、グラフの再描画

rinshu

総合スコア1

C#

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

Visual Studio

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

0グッド

0クリップ

投稿2021/10/28 05:09

編集2021/10/29 05:18

目標・プログラムの詳細

〇目標: コンボボックスの選択項目に応じた、グラフの再描画。

〇プログラムの詳細: 数値を格納している、3つのデータA,B,Cがある状況を仮定してください。
縦軸や横軸にしたいデータをコンボボックスから変更すれば、グラフが再描画されるプログラムを目指しています。

現状・問題・エラーメッセージ

〇現状: コンボボックス自体は選べる状態になっています。イメージ説明
軸ラベルは変更させることに成功しています。

〇問題: コンボボックスの項目を変更しても、グラフが再描画されません。

〇エラーメッセージ:
・System.ArgumentNullException: ''name' 引数を Null にすることはできません。:
comboBox1_SelectedIndexChanged内で

該当のソースコード

using

1using System.Data; 2using System.Windows.Forms; 3using System.Windows.Forms.DataVisualization.Charting; 4using System.Drawing; 5 6namespace windo 7{ 8 9 public partial class Form1 : Form  10 { 11 12 public Form1() 13 { 14 15 InitializeComponent(); 16 17 } 18 19 private void Form1_Load(object sender, EventArgs e) 20 { 21 22 chart1.Series.Clear(); 23 chart1.ChartAreas.Clear(); 24 25 // グラフを描く空間を生成 26 ChartArea chartArea = new ChartArea(); 27 chart1.ChartAreas.Add(chartArea); 28 29 // グラフの元となるデータの格納場所を生成 30 Series series1 = new Series(); 31 32       // データの格納表を作成 33 DataTable table = new DataTable(); 34 35 // データ名をつける 36 table.Columns.Add("A", typeof(double)); 37 table.Columns.Add("B", typeof(double)); 38 table.Columns.Add("C", typeof(double)); 39 40 // 表にデータを格納 41 table.Rows.Add(new Object[] { 1, 5000000, 55 }); 42 table.Rows.Add(new Object[] { 2, 4000000, 44 }); 43 table.Rows.Add(new Object[] { 3, 3000000, 33 }); 44 45       // コンボボックスに項目名を格納 46 comboBox1.Items.AddRange(new string[] { "A", "B", "C" }); 47 comboBox2.Items.AddRange(new string[] { "A", "B", "C" }); 48 49       // コンボボックスの説明をするテキストボックスを格納 50 textBox1.Text = "横軸のデータ"; 51 textBox2.Text = "縦軸のデータ"; 52 53 // コンボボックスの初期値を設定 54 comboBox1.SelectedIndex = 0; 55 comboBox2.SelectedIndex = 0; 56 57 //コンボボックスで選んだデータ名を読み込む 58 object Select_X = comboBox1.SelectedItem; 59 var X_Data = Select_X.ToString(); 60 object Select_Y = comboBox2.SelectedItem; 61 var Y_Data = Select_Y.ToString(); 62 63 //尋ねたデータ名を軸ラベルにする 64 chart1.ChartAreas[0].AxisX.Title = X_Data; 65 chart1.ChartAreas[0].AxisY.Title = Y_Data; 66 67       //データをグラフにプロット 68 for (int i = 0; i < table.Rows.Count; i++) 69 { 70 series1.Points.AddXY(table.Rows[i][X_Data], table.Rows[i][Y_Data]); 71 } 72 chart1.Series.Add(series1); 73 74 } 75 76     //コンボボックス1の項目を選び直した時の処理 77 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e,DataTable table) 78 { 79        80       //データの上書きのために、一度作ったseries1を消去 81 chart1.Series.Clear(); 82 83 //グラフの元となるデータの格納場所を生成 84 Series series1 = new Series(); 85 86       //コンボボックスで選び直したデータ名を読み込む 87 object Select_X = comboBox1.SelectedItem; 88 var X_Data = Select_X.ToString(); 89 object Select_Y = comboBox2.SelectedItem; 90 var Y_Data = Select_Y.ToString(); 91 92 //尋ねたデータ名を軸ラベルにする 93 chart1.ChartAreas[0].AxisX.Title = X_Data; 94 chart1.ChartAreas[0].AxisY.Title = Y_Data; 95 96       //データをグラフにプロット 97 for (int i = 0; i < table.Rows.Count; i++) 98 { 99 series1.Points.AddXY(table.Rows[i][X_Data], table.Rows[i][Y_Data]); 100 } 101 chart1.Series.Add(series1); 102 } 103 104     //コンボボックス2の項目を選び直した時の処理 105 private void comboBox2_SelectedIndexChanged(object sender, EventArgs e, DataTable table) 106 { 107 108   //データの上書きのために、一度作ったseries1を消去 109 chart1.Series.Clear(); 110 111 //グラフの元となるデータの格納場所を生成 112 Series series1 = new Series(); 113 114       //コンボボックスで選び直したデータ名を読み込む 115 object Select_X = comboBox1.SelectedItem; 116 var X_Data = Select_X.ToString(); 117 object Select_Y = comboBox2.SelectedItem; 118 var Y_Data = Select_Y.ToString(); 119 120 //尋ねたデータ名を軸ラベルにする 121 chart1.ChartAreas[0].AxisX.Title = X_Data; 122 chart1.ChartAreas[0].AxisY.Title = Y_Data; 123 124       //データをグラフにプロット 125       for (int i = 0; i < table.Rows.Count; i++) 126 { 127 series1.Points.AddXY(table.Rows[i][X_Data], table.Rows[i][Y_Data]); 128 } 129 130 chart1.Series.Add(series1); 131 } 132 } 133}

試したこと

① comboBox_SelectedIndexChangedを使用して、コンボボックスに関するイベントを発生させようとした
② オーバーロードやデリゲートの意味を調べた しかし、解決の糸口が見つからなかった

補足情報

Visual Studio 2019
.NET Framework 4.7.2

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/10/28 05:54

まず、何はともあれ、コードは ``` と ``` で囲ってください。インデントされて見やすくなるので。インデントされてないコードは質問者さん自身も読む気がしないのでは?
rinshu

2021/10/28 07:09 編集

ご回答ありがとうございます。 囲みました。
BluOxy

2021/10/29 04:25

コンパイルエラーが直っても 再描画できない という問題が解決しないのでしたら、「現状・問題・エラーメッセージ」欄にどういう問題で解決できていないのかを載せるとそれに対する回答がもらえるかもしれません。
rinshu

2021/10/29 04:34

BluOxyさん、ご回答ありがとうございます。
BluOxy

2021/10/29 09:44 編集

「デリゲート'EventHandler'に一致する'comboBox〇_SelectedIndexChanged'のオーバーロードはありません」が出ていたが解決した件は質問に残しておかないと、質問と回答が噛み合わなくなると思うので、その経緯は残したままの方が良いと思います。 (質問の編集履歴から以前残したメッセージを拾ってくることができますので、活用してください) 通常 1 つの質問ページに対して複数個の問題解決を試みようとすると必然的に質問の情報量が大きくなりますから、もし整理が難しいようなら、コンパイルエラーの件は解決したということでこの質問は閉じていただいて、別途質問を立てるのが良いかと思います。
guest

回答2

0

ベストアンサー

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e,DataTable table)

それは多分 Visual Studio のデザイナを使って自動生成させたイベントハンドラに質問者さんが引数 DataTable table を追加したのだと思いますが、そういうことはできません。引数は自動生成された object sender, EventArgs e で決め打ちでそれ以外はあり得ません。

Form_Load で作った DataTable をイベントハンドラ内で使いたいなら、以下のようにフィールドを追加して、

public partial class Form1 : Form  { private DataTable table; // これを追加 public Form1() {

Form1_Load で以下のようになっているところを、

DataTable table = new DataTable();

以下のようにしてみてはいかがですか?

this.table = new DataTable();

もちろん、イベントハンドラの引数 DataTable table は削除してください。

【追記】

下のコメント欄の 2021/10/30 11:10 の私のコメントで「後で回答欄に何がダメなのかと解決のための案を書いておきます。」と書いた件です。

コメント欄に書きましたように、質問者さんのコードをコピーして、上の回答で指摘したところは直して、試してみましたが「''name' 引数を Null にすることはできません」というエラーは出ません。質問に書いてないことをしてませんか?

そのエラーは出ませんが、質問のコードには以下の問題があって別のエラーが出ますし、そこを解決しても ComboBox の操作では期待したようには切り替わりません。

(1) 質問のコードの Form_Load で「コンボボックスの初期値を設定」としているところで ComboBox.SelectedIndexChanged イベントが発生する。comboBox1.SelectedIndex = 0; が先なのでまず comboBox1 のイベントハンドラに制御が飛ぶが、その時点では comboBox2.SelectedItem はまだ null なので Select_Y.ToString(); で NullReferenceException がスローされる。

SelectedIndex が null か否かをチェックして null だったら何もしないで return すれば回避できます。

(2) 質問のコードでは、ComboBox.SelectedIndexChanged イベントのハンドラと Form_Load の両方で Chart を生成しているが、上に書いたように Form_Load で「コンボボックスの初期値を設定」としているところでイベントが発生するので初期画面でダブってしまい、その後の ComboBox の操作でも意味不明な動きになる。

ComboBox.SelectedIndexChanged イベントのハンドラ内だけで Chart を生成すれば期待した動きになります。

検証に使ったコードを以下に書いておきます。質問者さんのコードをほぼコピペして、上に述べた回避策を取ったものです。

C#

1using System; 2using System.Data; 3using System.Windows.Forms.DataVisualization.Charting; 4using System.Windows.Forms; 5 6namespace WindowsFormsChart 7{ 8 public partial class Form2 : Form 9 { 10 private Chart chart1; 11 private DataTable table; 12 13 public Form2() 14 { 15 InitializeComponent(); 16 17 chart1 = new Chart 18 { 19 Location = new System.Drawing.Point(50, 50), 20 Width = 600 21 }; 22 Controls.Add(chart1); 23 } 24 25 private void Form2_Load(object sender, EventArgs e) 26 { 27 // ここでは Chart は作らない 28 29 table = new DataTable(); 30 31 // データ名をつける 32 table.Columns.Add("A", typeof(double)); 33 table.Columns.Add("B", typeof(double)); 34 table.Columns.Add("C", typeof(double)); 35 36 // 表にデータを格納 37 table.Rows.Add(new Object[] { 1, 5000000, 55 }); 38 table.Rows.Add(new Object[] { 2, 4000000, 44 }); 39 table.Rows.Add(new Object[] { 3, 3000000, 33 }); 40 41 // コンボボックスに項目名を格納 42 comboBox1.Items.AddRange(new string[] { "A", "B", "C" }); 43 comboBox2.Items.AddRange(new string[] { "A", "B", "C" }); 44 45 //コンボボックスの初期値を設定 46 comboBox1.SelectedIndex = 0; 47 comboBox2.SelectedIndex = 0; 48 } 49 50 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 51 { 52 //コンボボックスで選び直したデータ名を読み込む 53 object Select_X = comboBox1.SelectedItem; 54 object Select_Y = comboBox2.SelectedItem; 55 56 // Form_Load の comboBox1.SelectedIndex = 0; でイベントが発生 57 // した時は comboBox2.SelectedItem は null 58 if (Select_X == null || Select_Y == null) return; 59 60 var X_Data = Select_X.ToString(); 61 var Y_Data = Select_Y.ToString(); 62 63 chart1.Series.Clear(); 64 chart1.ChartAreas.Clear(); 65 66 // グラフを描く空間を生成 67 ChartArea chartArea = new ChartArea(); 68 chart1.ChartAreas.Add(chartArea); 69 70 // グラフの元となるデータの格納場所を生成 71 Series series1 = new Series(); 72 73 //尋ねたデータ名を軸ラベルにする 74 chart1.ChartAreas[0].AxisX.Title = X_Data; 75 chart1.ChartAreas[0].AxisY.Title = Y_Data; 76 77 //データをグラフにプロット 78 for (int i = 0; i < table.Rows.Count; i++) 79 { 80 series1.Points.AddXY(table.Rows[i][X_Data], table.Rows[i][Y_Data]); 81 } 82 chart1.Series.Add(series1); 83 } 84 85 private void comboBox2_SelectedValueChanged(object sender, EventArgs e) 86 { 87 //コンボボックスで選び直したデータ名を読み込む 88 object Select_X = comboBox1.SelectedItem; 89 object Select_Y = comboBox2.SelectedItem; 90 91 // Form_Load の「コンボボックスの初期値を設定」順であれば null になる 92 // ことはなさそうだが念のため 93 if (Select_X == null || Select_Y == null) return; 94 95 var X_Data = Select_X.ToString(); 96 var Y_Data = Select_Y.ToString(); 97 98 chart1.Series.Clear(); 99 chart1.ChartAreas.Clear(); 100 101 // グラフを描く空間を生成 102 ChartArea chartArea = new ChartArea(); 103 chart1.ChartAreas.Add(chartArea); 104 105 // グラフの元となるデータの格納場所を生成 106 Series series1 = new Series(); 107 108 //尋ねたデータ名を軸ラベルにする 109 chart1.ChartAreas[0].AxisX.Title = X_Data; 110 chart1.ChartAreas[0].AxisY.Title = Y_Data; 111 112 //データをグラフにプロット 113 for (int i = 0; i < table.Rows.Count; i++) 114 { 115 series1.Points.AddXY(table.Rows[i][X_Data], table.Rows[i][Y_Data]); 116 } 117 chart1.Series.Add(series1); 118 } 119 } 120}

結果は以下のようになります。

イメージ説明

投稿2021/10/28 06:53

編集2021/10/30 02:56
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

rinshu

2021/10/28 07:11

ご回答ありがとうございます。 アドバイス通りに修正しましたが、再描画はされません。
退会済みユーザー

退会済みユーザー

2021/10/28 08:09 編集

質問のエラーの問題は解消できて、アプリは実行できるようになったのですよね? であれば、Visual Studio のデバッガを使って、ステップ実行しながら変数を調べるなどして、どこに問題があるのか調べましょう。それがもっとも有効な原因究明の方法で、それができるのは質問者さんだけです。
rinshu

2021/10/29 04:35

ご回答ありがとうございます。 いまだに解決できていませんが、イベントの発生自体は成功しています。
退会済みユーザー

退会済みユーザー

2021/10/29 04:57

自助努力でデバッグを続けて原因究明にあたっているからしばらく待ってくれと言う中間報告ですか? もし聞きたいことがあるなら遠慮しないでそれを書きましょう。
rinshu

2021/10/29 05:33

アドバイスありがとうございます。 質問は1つあります。 答えていただけましたら幸いです。 ・質問: コンボボックス1の項目を選び直した時の処理で、datatableのデータを列指定して読み込む際の 列指定の仕方はどのようになりますか? ・詳細: ソースコードのようにaddxyを利用してデータプロットを試みました。 しかし、エラーメッセージ「''name' 引数を Null にすることはできません」と出てきました。 ・試みたこと: イベントループ内では初期値の設定でこの問題が解決しました。 しかし、イベントハンドラー内ではその方法は通用しませんでした。
退会済みユーザー

退会済みユーザー

2021/10/29 07:09

> エラーメッセージ「''name' 引数を Null にすることはできません」と出てきました。 質問に書かれたコードのどの行で出るのでしょう?
rinshu

2021/10/29 07:44

ご質問ありがとうございます。 以下のコード(3か所とも)で出ます。 for (int i = 0; i < table.Rows.Count; i++) { series1.Points.AddXY(table.Rows[i][X_Data], table.Rows[i][Y_Data]); } chart1.Series.Add(series1);
退会済みユーザー

退会済みユーザー

2021/10/29 08:58 編集

> 以下のコード(3か所とも)で出ます。 ということは ComboBox で切り替える以前の問題として、初期画面でも Chart が表示されないということですか?
退会済みユーザー

退会済みユーザー

2021/10/30 02:10

> 以下のコード(3か所とも)で出ます。 質問者さんのコードをコピーしてやってみましたが「''name' 引数を Null にすることはできません」というエラーは出ませんけど? ただ、他のところに問題があって ComboBox の操作では期待したようには切り替わりません。 後で回答欄に何がダメなのかと解決のための案を書いておきます。
rinshu

2021/11/01 01:28

ご回答ありがとうございました。 Form上でデータを選択する方法はあきらめました。
退会済みユーザー

退会済みユーザー

2021/11/01 01:46

> Form上でデータを選択する方法はあきらめました。 どういうこと?
rinshu

2021/11/01 01:50

目標自体をあきらめたということです。
退会済みユーザー

退会済みユーザー

2021/11/01 02:18 編集

> 目標自体をあきらめたということです。 目標って何なのですか? 少なくともあなたが質問に書いた範囲で、初期画面の表示および「目標: コンボボックスの選択項目に応じた、グラフの再描画」ができることは回答の追記でサンプルコードまで書いて可能であることは示したのですが。 質問に書いてない別の目標があってそれができなかったということ? XY問題になっていたということ?
guest

0

簡単に言うと、そんな引数知らんって言われてます。
イベントハンドラに勝手に引数足したんじゃないですか?
ComboBox.SelectedIndexChanged イベント
こちらを参照してください。

投稿2021/10/28 05:48

YAmaGNZ

総合スコア10222

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

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

rinshu

2021/10/28 07:11

ご回答ありがとうございます。 アドバイス通りに修正しています。
rinshu

2021/10/29 04:35

ご回答ありがとうございます。 いまだに解決できていませんが、イベントの発生自体は成功しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問