none
親フォームと子フォームとのデータのやり取り RRS feed

  • 質問

  • 子フォームにsetプロパティ を作って親フォームから子フォームにDataTable のデータを渡します。
    子フォームにあるDataGridView にDataTable のデータを表示することができます。
    子フォームは、Show() メソッドで表示しています。

                ChildForm form = new ChildForm();

    ChildForm へのデータは、set アクセサでDataTable を渡しています。

    この子フォームのデータに最初に渡したデータへの追加データとしてDataTable を追加しようと思います。
    もう一度、ChildForm form = new ChildForm(); というコードを使うと、ChildForm がもう一つ新しく表示されてしまって、
    データを追加したくても追加データを先ほど表示したChildForm に追加できません。

    もともとあるChildForm にデータを渡す方法が分かりません。
    どうしたら、もともとのChildForm に親フォームからデータを渡すことが出来るのでしょうか?

    よろしくお願いします。

    2010年2月28日 11:32

回答

  • こんにちは、横から失礼します。

    単純に、
    ChildForm form = new ChildForm();
    ってなっているメソッド内のform変数を、
    親フォームのメンバ変数に変えてあげて、
    追加したい時にnewしなければ良いのでは?

    そうした上で、DataRow追記用の
    Setプロパティを用意すれば済む話だと思いますけど・・・

    • 回答としてマーク yasheeki 2010年3月5日 15:57
    2010年3月4日 9:16

すべての返信

  • > この子フォームのデータに最初に渡したデータへの追加データとしてDataTable を
    > 追加しようと思います。

    「DataTable を追加」というのはどういう意味ですか?

    DataTable へのデータの追加といういみなら、ChildForm へは DataTable インス
    タンスへの参照値を渡しているはずなので、DataTable のインスタンスにデータを追
    加したなら、ChildForm の DataGridView にも追加した結果が反映されると思いま
    すが。

    見当違いでしたら失礼しました。

    2010年2月28日 12:08
  • 理解しにくい説明の質問で申し訳ありません。

    最初は、DataTable のインスタンスにデータを追加する
    というよりも、Form にDataTableを渡したのです。
    その渡し方は、ChildForm form = new ChildForm();
    form.AddData = firstTable;
    という風です。
    次にデータを渡すにあたって、改めて
    ChildForm form = new ChildForm();
    とすると、元のform にデータが渡せないのです。
    2010年2月28日 12:39
  •  次にデータを渡すにあたって、改めて
    > ChildForm form = new ChildForm();
    > とすると、元のform にデータが渡せないのです。

    たぶん、form.AddData = firstTable とした時点で以下のようになっていると思いま
    す。

    親 From のフィールド(DataTable インスタンスへの参照値)
        ↓
    DataTable のインスタンス(実体は同じもの)
        ↑
    子 Form のフィールド(DataTable インスタンスへの参照値)

    従って、親から DataTable のインスタンスにデータを追加しても、子から見てもその
    追加は反映されます。逆(子で変更したものが親にも反映される)も同様です。

    そういう話ではないのですか? (そもそも、インスタンスとか参照という意味を理
    解されているでしょうか?)

    2010年2月28日 14:11
  • その渡し方は、ChildForm form = new ChildForm();
    form.AddData = firstTable;
    という風です。
    次にデータを渡すにあたって、改めて
    ChildForm form = new ChildForm();
    とすると、元のform にデータが渡せないのです。
    最初の
    ChildForm form = new ChildForm();
    で、formには子フォームのインスタンスへの参照が入ります。・・・・・①
    次の
    ChildForm form = new ChildForm();
    で、formには子フォームのインスタンスへの参照が入ります。・・・・・②
    ここで、①と②の子フォームのインスタンスが存在することになります。つまり、①と②の二つの子フォームを作成しています。
    formという変数は一つしかありませんから、①では①の子フォームのインスタンスへの参照が入り、②では②の子フォームのインスタンスへの参照が入ります。つまり、form変数は②で①の段階での内容が上書きされてしまいます。
    したがって、最初に①で作成した子フォームのインスタンスをずっと使い続けたいのであれば、②は必要ありません。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2010年2月28日 15:26
    モデレータ
  • 親フォームのDataGridView には、DataTable のデータが表示されています。
    この親フォームのうち、Where句で取得されたDataTable を子フォームであるChildForm に渡します。

    ChildForm にDataTable を渡したときに、ChildForm のDataGridView にそのデータが表示されます。
    このChildForm はShow()メソッドで呼び出しているので、親フォームも操作可能です。
    次いで、親フォームから改めて追加データをChildForm を渡すにあたって、
    ChildForm form = new ChildForm();
    form.AddData = firstTable;
    では、新しい子フォームが出来てしまいますので、最初に
    ChildForm form = new ChildForm();
    で、出来たChildForm にデータを追加することは出来ません(よね?)。

    したいことは、親フォームのDataGridView のうちの一つのデータ行を
    ChildForm に追加したいのです。

    このChildForm は、Close()メソッドで閉じていなくて、
    Show()メソッドでどちらのフォームも操作可能な状態です。

    そこで、ChildForm を開いていながら、親フォームのDataGridView のうちのCurrentCell のデータを、
    改めて追加したいのですが、
    ChildForm.Show();
    のあとでは、ChildForm へ親フォームからデータを追加するにあたって、
    もともとあるChildForm へのデータの渡し方です。

    ChildForm.Show();
    の一行のあとで、親フォームのデータ追加ボタン(と名づけておきます)をクリックする操作で、
    子フォーム(ChildForm)にデータを渡すことができるのでしょうか?
    出来るのあれば、その方法はどうするんでしょうか?

    ということなのですが、説明が長い割に分かりづらくて申し訳ありません(同じことばの繰り返しが多くて)。
    (恥ずかしながら、こんな冗長な説明が作るコードにも反映されているのは、言うまでもありません)
    2010年3月1日 13:59
  • 説明が理解できませんが、以下のような感じなのでしょうか? それで、
    Where句で取得された DataTable への行の追加は親 Form で行うので
    しょうか?

    親 Form のフィールド1(参照値)→ オリジナルDataTable のインスタンス
         フィールド2(参照値)
          ↓
    Where句で取得されたDataTableのインスタンス(親子共通)
          ↑
    子 Form のフィールド(参照値)

    そうであれば、子 Form にデータを渡す必要はないと思いますけど、そういう
    話とは違うのでしょうか?

    2010年3月1日 14:24
  • Where句で取得された DataTable の行に対する、更なる行の追加は親 Form で行
    いたいと思っています。

    フィールド2は、Where句で取得された DataTable とは別に、親フォームで作られたDataTable なので、子 Formにはデータが渡されていない状態だと考えて下さい。

    追加するDataTable は、子フォームに渡すと同時に Union (とか)で一つのDataTable にしたいと思っているのです。

    今回、子フォ-ムにデータを渡すための方法を確認したいほか、子フォームに取得されたDataTable を親フォームで確認することもできるといいと思います。
    というのも、親フォームと子フォームとのデータのやり取りをしたいからという質問のタイトル通りなのです。
    やっぱり、質問の内容は意味不明でしょうか?(まずは、小学校で日本語を覚えなおした方がいいかもしれませんけれど...)

    よろしくお願いします。
    • 編集済み yasheeki 2010年3月2日 14:08
    2010年3月2日 11:23
  • > 分かりますでしょうか?

    すいませんが、何回読んでも理解不能です。というか、ますます分からなくな
    ってきました。

    「オリジナルDataTable のインスタンス」「Where句で取得されたDataTableの
    インスタンス」の他に、親子 Form が参照しているインスタンスがあるのです
    か?

    「追加するDataTable」とは何ですか? 

    それを「子フォームに渡す」というのはどういう意味ですか(「Where句で取
    得されたDataTableのインスタンス」に行を追加するだけとは違うのですか)?

    「Union (とか)で一つのDataTable にしたい」というのは、何と何をどのよう
    に一つにするのですか?

    2010年3月2日 14:03
  • たぶん、こういうことではないかと想像してみます。

    1.親フォームから子フォームへDataTableを渡し、子フォームでそのDataTableをDataGridViewで表示します。

    2.次に、親フォームで新たなDataTableを作成し、それを子フォームへ渡す。子フォームでは1.のDataTableに2.のDataTableを追加して、それをDataGridViewで表示する。

    そこで確認なのですが、

    >ChildForm へのデータは、set アクセサでDataTable を渡しています。

    と書かれていますが、親フォームのDataTableを子フォームへ単純に渡すだけでは、子フォームには親フォームのDataTableの在りか(これを参照と言います)を渡しているに過ぎません。DataTableを丸ごと渡しているわけではないのです。したがって、子フォームは親フォームにあるDataTableの在りかを知っているだけで、子フォームにDataTableそのものがあるわけではありません。つまり、親フォーム、子フォーム全体で、DataTableは一つしかありません。クラスのような参照型を渡すということは、こういうことです。
    ここまで理解できればSurferOnWwwさんが言われている、親フォームのDataTableをいじれば、それは自動的に子フォームに反映されるということが理解できると思います。なぜなら同じDataTableを親フォームも子フォームも扱っているのですから。
    まず、ここまではよろしいでしょうか?


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2010年3月2日 15:48
    モデレータ
  • ご解読有難うございます。

    >たぶん、こういうことではないかと想像してみます。

    >1.親フォームから子フォームへDataTableを渡し、子フォームでそのDataTableをDataGridViewで表示します。

    >2.次に、親フォームで新たなDataTableを作成し、それを子フォームへ渡す。子フォームでは1.のDataTableに2.のDataTableを追加して、それをDataGridViewで表示する。

    と、おっしゃる通りでございます。

    >親フォームのDataTableを子フォームへ単純に渡すだけでは、子フォームには親フォームのDataTableの在りか(これを参照と言います)を渡しているに過ぎません。

    というのも、分かりました。

    で、そこからどんな問題が起きてくるのでしょうか?

    渡したDataTable を別のテーブルに移し替えてしまえば、もとのDataTable との関係が切れるとか、でしょうか?

    よろしくお願いします。
    2010年3月3日 11:46
  • > 渡したDataTable を別のテーブルに移し替えてしまえば、もとのDataTable
    > との関係が切れるとか、でしょうか?

    そういう発言が出るようでは、インスタンスとか参照という意味を全く理解し
    ていませんね。

    そのあたりの基本的なことを理解してないと言葉が通じないので、掲示板で何
    回やり取りしても空回りするだけです。

    意味が分からなければ、検索して調べるなどして、少し勉強してください。例
    えば以下のページ。

    第3章 クラスとインスタンス
    http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_003/cs2_003_01.html

     

    2010年3月3日 12:50
  • こんにちは、横から失礼します。

    単純に、
    ChildForm form = new ChildForm();
    ってなっているメソッド内のform変数を、
    親フォームのメンバ変数に変えてあげて、
    追加したい時にnewしなければ良いのでは?

    そうした上で、DataRow追記用の
    Setプロパティを用意すれば済む話だと思いますけど・・・

    • 回答としてマーク yasheeki 2010年3月5日 15:57
    2010年3月4日 9:16
  • プロパティが
    public DataTable AddTable
            {
                get
                {
                    return addTable;
                }
                set
                {
                    addTable = value;
                }
            }

    DataTable firstTable;
    --------

    としているところで、
    ChildForm form = new ChildForm();
    form.AddData = firstTable;
    というのを

    クラスのメンバ変数に変更して
    ChildForm form;
    最初にDataTable を渡すときは、
    form = new ChildForm();
    として、
    次にDataTable を渡すときには
    ただ、form.AddTable = nextTable; // DataTable nextTable;
    とすればよいということでしょうか?

    ChildForm form = new ChildForm();
    という書式が本来のもので、
    ChildForm form;
    は、説明用に記述されているだけだと思っていたのですが、
    こんな効果があるとは思いませんでした。

    ---という、解釈でよろしいでしょうか?
    間違った解釈かも知れませんので、よろしくお願いします。
    2010年3月4日 12:10
  • 渡したDataTable を別のテーブルに移し替えてしまえば、もとのDataTable との関係が切れるとか、でしょうか?
    その通りです。
    インスタンスというのはわかってしまえば簡単なのですが、わからないければなかなか理解しづらいかもしれませんね。たとえば、
    ChildForm form = new ChildForm();
    のようにnewによってインスタンスが作成されますが、それは親フォームの中に作成されるわけではないのです。ヒープという特別なところに作成されます。そして、その在りかが、
    ChildForm formのformにセットされるのです。決してform変数にChildFormのインスタンスそのものが入るのではありません。
    DataTableでも何でもインスタンスは全て同じです。したがって、親フォームから子フォームにDataTableを渡すとは、ヒープにあるDataTableの在りか、言ってみれば住所みたいなものを渡しているのです。住所が手に入るので、子フォームからヒープにあるDataTableにアクセスできるようになります。つまり、以下のようなイメージになります。

                            ヒープにあるDataTable
                                          |
                 +------------------+---------------------------------+
                 |                                                                   |
                 |                                                                   |
             親フォーム                                                   子フォーム
    (ヒープにあるDataTableの在りかを知っている)            (ヒープにあるDataTableの在りかを知っている)

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2010年3月4日 14:34
    モデレータ
  • ChildForm form = new ChildForm();
    って書いている訳ですから、 new なんですよね・・・

    ヒープに関する認識ももちろん重要ですが、今回の場合はインスタンスを新しく生成しているという部分を理解するのが重要かと思いますよ。
    ついでにスコープも。

    ちなみに、メンバ変数にするのであれば、個人的には

    ChildForm form;

    ではなく

    private ChildForm form;

    または

    protected ChildForm form;

    と書くべきだと思います。
    ※スコープの意識が抜けたコーディングは、後で思わぬ障害が出かねませんので。

    2010年3月5日 2:46
  • aviator__さん、有難うございます。
    今回教えていただいた方法で、やっと親子フォームでのデータの受け渡しが出来るようになりました。

    また、SurferOnWwwさんのご紹介いただいたコラムも大変役に立ちました。基礎にもどって理解する機会が出来ました。
    さらに、trapemiyaさんには、面倒な読解までしていただいて、感謝しています。

    日本語の勉強もさることながら、人に伝えられるように用語を覚えないといけないかもしれません。
    もう少し、ヘルプを参考にすることで解決できるようにしていきたいものですが。
    2010年3月5日 15:57