こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

C# Form間のデータの受け渡し

Form2のテキストボックスとコンボボックス内のテキストをForm1のdataGridViewに転記したいと思っているのですがうまくいかず悩んでいます.

//datagridveiwに添付
DataGridView f1_Text = (DataGridView)f1.Controls["dataGridView1"];
f1_Text.Rows.Add(Text1, Text2, "→", Text3, Text4);

上記のようなプログラムを組んで走らせると下記のようなエラーとなってしまいます.
NullReferenceException
オブジェクト参照がオブジェクト インスタンスに設定されていません。

Text1~Text2はそれぞれテキストボックスとコンボボックスのテキストになります.
どなたか,どうすればよいかご教授頂けませんでしょうか?

投稿日時 - 2012-07-10 09:16:44

QNo.7582043

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(15)

ANo.15

>>私は技術的理由で「お勧めしない」といってるわけじゃないので技術的理由で「お勧めしない」といってる方にお尋ねください。

了解しました。そのようにします。

質問への回答を書いておきます。
TabControlからDataGridViewが取得出来ないのは、コントロールの階層を誤っているからでしょう。
TabControlからカレントのTabPageを取得して、TabPageからDataGridViewを取得します。
手順としては、

TabControl tb = (TabControl)this.f1.Controls["tabControl1"];
TabPage page = (TabPage)tb.TabPages[tb.SelectedIndex];
DataGridView grid = (DataGridView)page.Controls["dataGridView1"];
grid.Rows.Add("test");

となります。
質問と似たような状態を作成してVisual C# 2010で試していますが、取得に失敗した時のことは考慮していないので、適切に対策を講じて下さい。

投稿日時 - 2012-07-15 23:11:01

ANo.14

>質問者も#1もControlsプロパティを使用して操作していたのに、「何故お勧めできないのか」の技術的な理由を訊いたら、

私は技術的理由で「お勧めしない」といってるわけじゃないので技術的理由で「お勧めしない」といってる方にお尋ねください。

投稿日時 - 2012-07-15 22:22:50

ANo.13

#12を投稿した時に更新されていたので、追記しておくと、

>>「技術的理由ではなくて設計思想上の理由」と答えてるのにそれを無視して技術的理由とし解釈しようとしてたわけですか。それは話が通じるわけないですね。
>>私は「技術的に問題があるからお勧めしない」といってるわけじゃないですから。

ウチは技術的理由を求めたんだけどねえ。

>>そもそもContorolsがpublicなプロパティ(この場合は変数でも変わらないでしょうが)という事を知らないのであれば「他フォームのControlを直接操作するのはお勧めしない」ということもいえないと思いますが?

「ということもいえないと思いますが」とかそういう話じゃなくて、貴殿の事ですよ。知らなかったんでしょ。

>>フォームにメソッドなりプロパティを用意すると書いてるのもControlを取得するためのメソッドやプロパティを用意しましょうと書いてるんじゃなく、値を取得したり設定するためのメソッドやプロパティを用意するということなんですけど。
>>それにControlsプロパティを使って他フォームから直接操作した場合、そのフォームの画面構成が変わった場合にその操作を行ってるフォーム全てを書き直すことになりかねませんが(これも#6に書いてます)

ウチは技術的理由を求めたんだけどねえ。

投稿日時 - 2012-07-15 20:40:45

ANo.12

>>「Controlsがプロパティであることをお前は知らなかったんだろう」と決めつけのコメントされても・・・

質問者も#1もControlsプロパティを使用して操作していたのに、「何故お勧めできないのか」の技術的な理由を訊いたら、

>>仮にフォームAとしますけどフォームAのコントロールを他のフォームBが直接操作するためにはpublic(internalとかもありますが)にする必要があります。
>>これをクラスで考えた場合、クラスAのメンバ変数を他のクラスから操作させるがためにpublicにするというのと同じだと思います。
>>通常はクラスAにアクセスするためのメソッドを用意するなりクラスAのプロパティとして定義したりすると思いますが、いかがでしょうか?

なんて文言が返って来た。「Controlsはパブリックなプロパティ」なのに。これは如何に?

>>タイマースレッドだしたのは1例としてあげただけのはずですが。
>>フォームが増えた場合の話も出してるのに、勝手に人の話をそれだけの限定したものにしないでください。

申し訳ないけど、ウチはこういうやり取りが一番嫌いでねえ。話をまとめると、

・シングルスレッドの場合は、Controlsプロパティで操作しても技術的な問題はない。
・マルチスレッドの場合は、別スレッドからControlsプロパティで操作するのは技術的な問題があると。

上記2項目のいづれもFormの数に関わらずですよ。
ただ、それ以外に技術的な問題があると言うのなら、MSDNを交えて簡単にご説明頂ければと。

>>人の話をねじ曲げて解釈してコメントされても困ります。

捻じ曲げたつもりは無いんだけど、もうちょっと技術的な返答をしてほしいと言うのが本音ですなあ。

投稿日時 - 2012-07-15 19:30:38

ANo.11

>>>デリゲートを使った例は書きましたけど私の主張してるのは「他のフォームのコントロールを直接操作するのはお勧めしない」ですし。

>いや、質問は別Form上のDataGridViewの操作の仕方でしょ。だから質問者も#1もControlsプロパティを使用して操作しているのでしょ。
>で、ウチが「何故お勧めできないのか」の技術的な理由を訊いたら、

>>>通常はクラスAにアクセスするためのメソッドを用意するなりクラスAのプロパティとして定義したりすると思いますが、いかがでしょうか?

>なんて意味不明な妄言が出て来たと。要はControlsがプロパティである事を知らなかったんでしょ。
>そんな御仁の主張など無意味だわな。

「技術的理由ではなくて設計思想上の理由」と答えてるのにそれを無視して技術的理由とし解釈しようとしてたわけですか。それは話が通じるわけないですね。

私は「技術的に問題があるからお勧めしない」といってるわけじゃないですから。

そもそもContorolsがpublicなプロパティ(この場合は変数でも変わらないでしょうが)という事を知らないのであれば「他フォームのControlを直接操作するのはお勧めしない」ということもいえないと思いますが?

フォームにメソッドなりプロパティを用意すると書いてるのもControlを取得するためのメソッドやプロパティを用意しましょうと書いてるんじゃなく、値を取得したり設定するためのメソッドやプロパティを用意するということなんですけど。
それにControlsプロパティを使って他フォームから直接操作した場合、そのフォームの画面構成が変わった場合にその操作を行ってるフォーム全てを書き直すことになりかねませんが(これも#6に書いてます)

投稿日時 - 2012-07-15 18:58:44

ANo.10

>いや、Controlsがプロパティである事自体、ウチがMSDNを突き付けて初めて知ったんでしょ。
(以下略)

「Controlsがプロパティであることをお前は知らなかったんだろう」と決めつけのコメントされても・・・

>タイマースレッドも別スレッドで非同期動作するマルチスレッドの一つなんだけど。

タイマースレッドだしたのは1例としてあげただけのはずですが。
フォームが増えた場合の話も出してるのに、勝手に人の話をそれだけの限定したものにしないでください。

>NetFrameworkは広大なものだから全部理解する事は不可能だけど、何かを主張するなら、ある程度はMSDNなり書籍なりで調べてもらわないとねえ。

人の話をねじ曲げて解釈してコメントされても困ります。

投稿日時 - 2012-07-15 17:40:20

>>そうですね。
>>Contorolsはpublicなプロパティですね。
>>でも私はControlsプロパティがpublicなのはVisualStudioのデザイン画面(のプログラム)のためだと思ってますから。
>>だからといってControlsプロパティを使うなとはいうつもりはありません。
>>使う必要があるなら使えばいい。

いや、Controlsがプロパティである事自体、ウチがMSDNを突き付けて初めて知ったんでしょ。

>>誰がマルチスレッドだけを前提にした話をしてたんでしょう?

タイマースレッドも別スレッドで非同期動作するマルチスレッドの一つなんだけど。

>>デリゲートを使った例は書きましたけど私の主張してるのは「他のフォームのコントロールを直接操作するのはお勧めしない」ですし。

いや、質問は別Form上のDataGridViewの操作の仕方でしょ。だから質問者も#1もControlsプロパティを使用して操作しているのでしょ。
で、ウチが「何故お勧めできないのか」の技術的な理由を訊いたら、

>>通常はクラスAにアクセスするためのメソッドを用意するなりクラスAのプロパティとして定義したりすると思いますが、いかがでしょうか?

なんて意味不明な妄言が出て来たと。要はControlsがプロパティである事を知らなかったんでしょ。
そんな御仁の主張など無意味だわな。

>>誰にとって当たり前の話なんでしょう?
>>少なくとも今の私にとっては当たり前じゃないんですが、.NET使い始めのころはやってた気はしますけど。

さあ「.NET使い始めのころはやってた気はしますけど」なのに、何でControlsがプロパティである事を知らないんだろう。
NetFrameworkは広大なものだから全部理解する事は不可能だけど、何かを主張するなら、ある程度はMSDNなり書籍なりで調べてもらわないとねえ。

投稿日時 - 2012-07-15 12:21:54

ANo.8

>いかがでしょうも何も、ControlsってのはWindowsFormsで定義されているパブリックのプロパティだぞ。
>要は自作した全てのFormにはControlsというパブリックのプロパティが存在する。

そうですね。
Contorolsはpublicなプロパティですね。
でも私はControlsプロパティがpublicなのはVisualStudioのデザイン画面(のプログラム)のためだと思ってますから。
だからといってControlsプロパティを使うなとはいうつもりはありません。
使う必要があるなら使えばいい。

でもフォームが他のフォームのコントロールを直接操作しないと実現できないことってそんなにあるんですか。

>スレッドセーフにするのならデリゲートを使用しないとまずいんだが、そもそもマルチスレッドのGUIアプリなんて、マルチスレッド前提のソースが必要になるから、将来的にマルチスレッドになるかもしれないなんて言う想定レベルのソースじゃ話にならない。
>シングルスレッドのGUIアプリなら、インスタンス外からFormのControlsプロパティを操作するのは当たり前の話。

誰がマルチスレッドだけを前提にした話をしてたんでしょう?
デリゲートを使った例は書きましたけど私の主張してるのは「他のフォームのコントロールを直接操作するのはお勧めしない」ですし。
誰にとって当たり前の話なんでしょう?
少なくとも今の私にとっては当たり前じゃないんですが、.NET使い始めのころはやってた気はしますけど。

質問者の方には関係ない話で申し訳ありません。

投稿日時 - 2012-07-14 16:45:05

>>仮にフォームAとしますけどフォームAのコントロールを他のフォームBが直接操作するためにはpublic(internalとかもありますが)にする必要があります。
>>これをクラスで考えた場合、クラスAのメンバ変数を他のクラスから操作させるがためにpublicにするというのと同じだと思います。
>>通常はクラスAにアクセスするためのメソッドを用意するなりクラスAのプロパティとして定義したりすると思いますが、いかがでしょうか?

いかがでしょうも何も、ControlsってのはWindowsFormsで定義されているパブリックのプロパティだぞ。
要は自作した全てのFormにはControlsというパブリックのプロパティが存在する。

http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.controls.aspx
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.form.aspx

スレッドセーフにするのならデリゲートを使用しないとまずいんだが、そもそもマルチスレッドのGUIアプリなんて、マルチスレッド前提のソースが必要になるから、将来的にマルチスレッドになるかもしれないなんて言う想定レベルのソースじゃ話にならない。
シングルスレッドのGUIアプリなら、インスタンス外からFormのControlsプロパティを操作するのは当たり前の話。

投稿日時 - 2012-07-14 12:50:39

ANo.6

>何で?
>どう言う技術理由?

技術理由というよりは設計思想上の理由といった方があってるかもしれません。

http://okwave.jp/qa/q7487579.htmlの#1の回答者の方も書かれていますがコントロールを操作するのは、そのコントロールを所有するフォームの仕事だからです。

仮にフォームAとしますけどフォームAのコントロールを他のフォームBが直接操作するためにはpublic(internalとかもありますが)にする必要があります。
これをクラスで考えた場合、クラスAのメンバ変数を他のクラスから操作させるがためにpublicにするというのと同じだと思います。
通常はクラスAにアクセスするためのメソッドを用意するなりクラスAのプロパティとして定義したりすると思いますが、いかがでしょうか?

またフォームAのコントロールを操作するのがフォームBひとつだけの場合はまだいいですが、フォームC,フォームD…フォームに限らずバックグラウンドのタイマースレッドからなど多数出てきた場合、フォームAのコントロールなのにそのコントロールを操作するコードが各所に散らばるという事態になりかねません。さらにその散らばった状態でコントロールが全く別のコントロール型に仕様変更になったらそれら全て書き換えますか?少なくとも私はそんなことしたくありませんが。

なのでコントロールを所有するフォーム以外のフォームが直接操作するのはお勧めしませんし、コントロールの操作はそのコントロールを所有するフォームがするようにすべきと私は思います。
絶対やるなとはいいませんけど。

投稿日時 - 2012-07-13 22:14:48

#4
>>フォームから他のフォームのコントロールに直接値を設定することはしない方がいいと思いますよ。

何で?
どう言う技術理由?

投稿日時 - 2012-07-12 19:43:10

ANo.4

以前にも似たような質問あったのですがフォームから他のフォームのコントロールに直接値を設定することはしない方がいいと思いますよ。
と、その似たような質問探してみたらご本人でしたか・・・

http://okwave.jp/qa/q7482551.html
http://okwave.jp/qa/q7487579.html

投稿日時 - 2012-07-10 21:57:12

ANo.3

Wr5

>Form1を表示した後にForm2を表示します.また,dataGridViewはtabcontlorの中にあります.

でしたら、DataGridView自体は存在していますね。

f1.Controls["タブの名前"].Controls["対象のDataGridViewがあるTabPageの名前"].Controls["dataGridView1"]
という感じに辿っていくか…

先の回答でのページのようにthis.Controls.Find("dataGridView1", true)で検索して引っ張り出すか…でしょうか。
# 同じ名前がなければControl[]の先頭が対象のコントロールになるハズです。
# 1つしかなくてもControl[]で返されるコトになりますが。
DataGridView f1_Text = (DataGridView)(f1.Controls.Find("dataGridView1", true)[0]);
で行けますかねぇ……。

投稿日時 - 2012-07-10 11:23:04

ANo.2

Wr5

>今,確認したところf1_Textがnullになっていました.

Form2の該当箇所が実行される時にForm1が生成されていない…とか、DataGridViewが生成されていない…とかではないでしょうか?
表示の順番とかどうなっていますか?

対象のDataGridViewがTabPagesの中だったりGroupBoxの中だったりするとf1.Controls[]で取得できないかも知れませんが…その辺りは大丈夫ですか?
# Panelの上に設定した場合も…でしょうかね。
http://dobon.net/vb/dotnet/control/findcontrolbyname.html

投稿日時 - 2012-07-10 09:57:16

補足

Form1を表示した後にForm2を表示します.また,dataGridViewはtabcontlorの中にあります.

この場合,どのようにすればよろしいでしょうか?

ご教授よろしくお願いいたします.

投稿日時 - 2012-07-10 10:30:41

ANo.1

Wr5

f1_Text.Rows.Add(Text1, Text2, "→", Text3, Text4);
の行にブレークポイントを設定します。

で、ブレークした時にf1_Textはどうなっていますか?
f1.Controls["dataGridView1"];
で取得できていないのではありませんか?

f1の方がnullで落ちている。
という可能性もあるかも知れませんが……。

投稿日時 - 2012-07-10 09:26:14

補足

今,確認したところf1_Textがnullになっていました.

正しく取得させるにはどうすればよろしいでしょうか?

重ねてご教授よろしくお願いいたします.

投稿日時 - 2012-07-10 09:36:49

あなたにオススメの質問