- - PR -
C#: MDI子フォームから親フォームへのアクセス方法
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-02-24 11:11
MDI形式のWindowsアプリケーションについての質問です。
どうにも実現手法が見出せずにいます。 根本的なところが分かっていないからだと思います。 ご助言を頂けたら幸いです。VC# 2003 です。 [状況説明] (1)親フォーム(FormParent)と子フォーム(FormChild)があります。 (2)親フォームには ToolBar や StatusBar があります。 (3)親フォームは本アプリEXEを作るプロジェクトに属し、 子フォームはDLLプロジェクトに属します。 親フォーム側のプロジェクトでは、 子フォーム側のプロジェクトを参照設定にて加えています。 ※DLLに分けている理由は以下のとおりです。 ・子フォームが数種あり、いずれも(表現が悪いかもしれませんが) “孫フォーム”に相当する基底クラスがあり、 フォーム継承によって出来上がっています。 ・基底クラス(上の“孫フォーム”)はDLLに分けないと、 フォーム継承が出来ないとの認識です。 ・さらにそこから派生させた数種の子フォームも、 他のアプリでの利用を将来的に考えてDLLとしました。 [やりたいこと] ・子フォームが開いた後、子フォーム内のユーザアクションや処理 に応じて、親フォームの ToolBar や StatusBar にアクセスしたい。 ToolBar については、例えば特定ボタンの Pushed 状態を変更する ものです。 StatusBar については、子フォーム上での処理に応じて、 単純に何らかのテキスト表示を行うものです。 [実現できずに困っていること] ・一言でいいますと、子フォーム上のコードにて、親フォームを 認識できない点です。 状況説明(3)のような、親子を2つの(別々の)プロジェクトに分ける ことを止めて(フォーム継承もとりあえずなしにして)、 同一プロジェクト内に実装すれば、子フォーム側から、 親フォームの StatusBar にアクセスする例として parent.statusBar1.Text = "FormChild opened."; のように実現できます。(種々の前提ご説明省略します。) ・ところが状況説明(3)を実現すると、 親フォーム(FormParent)を子フォームにて宣言したりキャストしたり が出来ません。従って親フォーム側の public なフィールドなり メソッドなりにアクセス出来ません。 子フォームプロジェクトに、親フォームプロジェクトを参照設定 することができないからでしょうか。 (できないのは当たり前でしょうか。) フォーム継承やプロジェクト分割、それに対する参照設定に、 何か見落とし・勘違い・誤りがあるのでしょうか。 全般に理解不十分なところや、解決方法につきまして、 ご教示頂けましたら幸いです。 | ||||||||
|
投稿日時: 2005-02-24 11:40
回答ではありません。
まずは動かす。からはじめましょう。 クラスが依存しあっていても、当面は目をつぶります。 コードが汚くなったらリファクタリングをしましょう。 動いていないのでは、ほかのアプリでの利用という将来は来ないです。 動いていたとしても、そのままそのDLLを流用するという将来が来る可能性はかなり低いですよ。そういうもんなんです。 _________________ たつごろー http://www.codeseek.net MCSE MCSD.NET、MCDBA、MCSA、MCAD Oracle Master Platinum 9i、Oracle Master Linux+ [ メッセージ編集済み 編集者: たつごろー 編集日時 2005-02-24 11:41 ] | ||||||||
|
投稿日時: 2005-02-24 12:00
子フォームは、親フォームを単なるForm型としか認識していないので、
そこにToolbarがあるとか、Statusbarがあることは分かりません。 「StatusBar表示を変更する」など、親フォームが公開する操作・属性を 定めて、それを子フォームと共有する必要があります。 たとえば、子フォームのDLLに親フォームの基底クラスを導入し、 親フォームEXEから参照する、という方法があると思います。 | ||||||||
|
投稿日時: 2005-02-24 12:26
循環参照になるので、できないと思います。 また、EXEだとかDLLだとかは「配置」の問題であり、その前段階の クラス設計が適切な限りはある意味どうにでもなります。 配置の問題を早くに考えすぎると、そこで配置上の制約が発生し、 場合によっては失敗を招く気がします。
別のDLLにしなくても、継承はできると思うのですが・・・ [ メッセージ編集済み 編集者: kanai 編集日時 2005-02-24 12:37 ] | ||||||||
|
投稿日時: 2005-02-24 13:08
返信ありがとうございます。
kanai様のお話にありましたように、 間に親フォームの基底クラスを入れたら、という件から、 何かが出来そうな気がしてきました。 ただしちょっと試した限りでは、なかなかうまくできなくて もう2、3日、確認してから、ご報告致したく存じます。 たつごろー様からは、まず動くものを、との話を頂戴致しましたが、 フォーム継承やプロジェクト分割を止めれば、 何の苦労もなく実現できるであろうと承知しているところです。 ただ本件状況を除くと、フォーム継承により思い通りに動いており、 ここまでに実装した機能はそのままに、何か良い手はないかと 質問させて頂いた次第です。 ところで、kanai様の
は、そうなんですか?... よく認識していませんで、 そうしなければいけないものと勝手に思い込んでおりました。 即座のご報告ができませんが、確認出来次第に。 ありがとうございました。 | ||||||||
|
投稿日時: 2005-02-24 13:22
インターフェースを導入すれば簡単に解決します。 単純化したモデルケースは以下のとおり。 ・新規にクラスライブラリプロジェクトを作成し、IFormParent インターフェースを定義する。 ・IFormParent インターフェースに「親フォームが子フォームに公開するべきメソッド、プロパティ」を追加する。 ・IFormParent のプロジェクトを、親フォームおよび子フォームのプロジェクトから参照する。 ・FormParent の派生元に IFormParent を追加する。 ・FormParent に、IFormParent が規定するメソッド、プロパティを実装する。 FormChildXXX は IFormParent parent = (IFormParent) this.Parent; parent.DoSomeTHing(); のように、親フォームへのアクセスを確保します。 _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://hidori.jp/ // Microsoft MVP for Visual C# // // @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/ | ||||||||
|
投稿日時: 2005-02-24 13:28
渋木宏明(ひどり)様、ありがとうございます。
インターフェースですか。全く頭にありませんでした。 というのも、見聞きするだけで、取り扱った経験がないためです。 結末は後にご報告させて頂きます。 | ||||||||
|
投稿日時: 2005-02-24 22:36
渋木宏明(ひどり)様に示して頂いた、
インターフェースを用いる方法で 簡単に実現できました。 ただ (IFormParent) this.Parent は (IFormParent) this.ParentForm としました。 (IFormParent) this.MdiParent でもよい? いとも簡単に実現でき、感動しております。 大変勉強になりました。ありがとうございました。 |
1