- PR -

複数のフォーム間でのコントロールのやりとり

投稿者投稿内容
さすけ
常連さん
会議室デビュー日: 2004/04/10
投稿数: 38
投稿日時: 2004-04-10 00:34
初めての投稿になりますので不手際などあるかもしれませんが
ご指導のほど宜しくお願い致します。

フォームAでDataGrid、DataSet、DataViewを作成し、
フォームBからフォームAのDataViewやDataGridに対するプロパティの変更
やメソッド呼び出しを行う方法を教えて頂けないでしょうか?

宜しくお願い致します。

以上
ant
常連さん
会議室デビュー日: 2004/03/24
投稿数: 44
投稿日時: 2004-04-10 02:06
フォームAに追加されたコントロール(DataGrid、DataSet、DataView)
をpublicメンバとして公開しておくか、フォームAにpublicプロパティを
追加しておけばいいと思います。
さすけ
常連さん
会議室デビュー日: 2004/04/10
投稿数: 38
投稿日時: 2004-04-10 10:07
親切にご回答ありがとうございます。

サンプルファイルとして下記のプログラムを利用させて頂き、動きを確認させて頂いております。

http://ukamen.hp.infoseek.co.jp/Programming1/DataGrid/index.htm

上記のサンプルにForm2を作成し、Form2からForm1のDataViewやDataGridに対して
プロパティの変更やメソッドを呼び出そうとしています。

private System.Windows.Forms.DataGrid dataGrid1;
をpublic System.Windows.Forms.DataGrid dataGrid1;
に変更してForm2からForm1.DataGridをアクセスするとVisual Studio .net 2003
のコンパイラが静的でないプロパティにアクセスできませんといったメッセージが
表示されビルドできません。

また、public static System.Windows.Forms.DataGrid dataGrid1;に変更しても
コンパイラがメッセージを表示し、ビルドできません。

また、publicプロパティを新規に作成し、Form2から上記と同じようにアクセスしても
コンパイラがメッセージを表示し、ビルドできません。


何か解決方法があれば教えて頂ければ助かります。

以上
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-04-10 10:31
コンパイラがメッセージを表示しているなら、
「コンパイラが・・・というメッセージを表示し、ビルドできません。」
と書くと、読んだ方も何が問題なのか分かって問題解決がスムーズに進むと思います。

で、本題ですが「静的でないプロパティにアクセスできません」というのは、「静的(static)でないメンバ」を「静的なメンバ」のようにコーディングした場合のメッセージです。
つまり、newしたインスタンスのメンバとしてではなく、クラスそのもののメンバとしてアクセスしているということです。以下の例を参照してください。

ArrayList ar;
ar = new ArrayList();
ar.Sort();   ←インスタンスのメンバとして
ArrayList.Sort();   ←クラスのメンバとして(エラー)

Sort()は静的でないメンバなので、ArrayList.Sort()とは書けません。
だからといって「public static System.Windows.Forms.DataGrid dataGrid1;に変更」などとするのは本末転倒です。
コンパイルは通るようになるかもしれませんが、dataGrid1がForm1のインスタンスのメンバではなくなってしまうからです。

現在画面にウィンドウを表示しているForm1のインスタンスへの参照をForm2のインスタンスへ渡してあげてください。
Form2のインスタンスからはそれを使ってdataGrid1にアクセスできると思います。

(普通はコントロールをそのまま外部には公開しないでしょうけど)

[ メッセージ編集済み 編集者: 一郎 編集日時 2004-04-10 10:31 ]
さすけ
常連さん
会議室デビュー日: 2004/04/10
投稿数: 38
投稿日時: 2004-04-10 11:51
一郎様
大変ご丁寧な回答ありがとうございます。
全くな素人プログラマで申し訳ございません。

>(普通はコントロールをそのまま外部には公開しないでしょうけど)
普通は、どうやるのが正しいのでしょうか?

ぜひ教えて頂ければ幸いです。

メッセージの記載につきましては、申し訳ございませんでした。
手元にコンパイラがなく質問をしたためうる覚えのメッセージになってしまいました。

あわせてお詫び致します。

以上
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-04-10 12:29
諸農です。

引用:

>(普通はコントロールをそのまま外部には公開しないでしょうけど)
普通は、どうやるのが正しいのでしょうか?

ぜひ教えて頂ければ幸いです。



普通かどうかは別として、コードスケルトンがprivateで
メンバ公開しているので、既にantさんからもコメントが
あるようにアクセスメソッドやプロパティ等を利用して利
用したい情報にアクセスできるように公開するのが定石か
もしれません。

アクセスメソッドやプロパティの実体の実装は、当然、そ
れを「どう使いたいのかを考えている人の仕様に依存」するので、
現時点では日本語による方法論は提示できても「具体的なコード」は
書けないと思います。

入門書などには、カスタムFormクラスへのpublicメンバや
プロパティの追加方法等が解説されたものがありますので、
それらを参考にした方がベターかと思われます。

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
さすけ
常連さん
会議室デビュー日: 2004/04/10
投稿数: 38
投稿日時: 2004-04-10 12:46
諸農様

大変、丁寧な回答ありがとうございました。
おおよそ理解しましたので、市販本で学習を行い経験を積んで
いきたいと思います。

これからも宜しくお願いいたします。

以上
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-04-10 13:22
長くなっちゃった。
気が向いたら読んでみて下さい。
-------------------

クラスやインスタンス、メソッド、プロパティ等は、その外部との関係使命(つまり役割)について意識しながら作り、そして使ってください。

Form2の使命はなんでしょうか。
Form2からForm1のDataViewやDataGridに対してプロパティの変更やメソッドを呼び出そうとしているようですが、それがForm2の使命ですか?Form2でボタン等を押下などした結果そうなってほしいだけではないですか?

Form1の所有物であるdataGrid1の状態を変更するのはForm1の使命です。(普通は)
Form1の所有物であるdataGrid1を外部からの指示で書き換える必要があるのなら、Form1がそういったサービスを外部に提供する必要があります。
例えばRefreshDataGrid()のようなメソッドを用意するといったような。

どのようなものを作っているのか分からないので適当なことを書きますが、例えばForm2でデータベースからデータを取ってくる条件を指定して、「この条件で再表示」ボタンを押したらForm1のdatagrid1が書き換わるというようなプログラムだったとしたら、Form2の使命は「データの取得条件をユーザーから取得する」ということになると思います。
その場合、「この条件で再表示」ボタンを押されたということは、ユーザーから再取得してほしいという意思表示をされたということですので、Form1に「この条件でデータを再取得してほしいようですよ」という情報を伝えるべきです。そして伝えることだけするべきです。
実際に再描画するのはForm1です。

Form1の使命も考えてください。
Form1の使命が「ユーザーにグリッド形式でデータを表示する」ということなら、DataGridでなくて例えばGrapeCity社のUltraWinGridを使っていても構わないわけですよね。
でもそのように変更した場合、今回のようにForm2から直接dataGrid1にアクセスしていると困ります。
このような「使命をまっとうできる別の方法に置き換えてみて、外部に影響を受けるオブジェクトがないか」を考えてみるテストは、オブジェクト同士が許される関係を超えて密に結びついていないかテストするのに使います。結合度のテストです。
実際にUltraWinGridを使う可能性があるかどうかは問題ではありません。テストですので。

この考え方はFormの中でも見ることができます。
Form1がdataGrid1を書き換えたいと思っても、結局dataGrid1が提供しているサービス(メソッドやプロパティ)を使うしかありません。Form1がdataGrid1の存在しているアドレスのメモリの値を直接変更したりするわけではありません。
それは、メモリへのデータの保存の方法が変わった場合にDataGridは同じ使命を提供しているにもかかわらすForm1には不都合が生じるように許される関係を超えてしまうからです。

外からはDataGridに「書き換えてくれ」とお願いするしかできないわけです。
DataGridを書き換えるのはDataGridの使命だからです。

[ メッセージ編集済み 編集者: 一郎 編集日時 2004-04-10 13:26 ]

スキルアップ/キャリアアップ(JOB@IT)