none
子フォームから親フォームをアクティブにしたい RRS feed

  • 質問

  • 親フォーム(ParentForm)からShow()メソッドで子フォーム(ChildForm)を呼び出して表示しています。

    親フォームをアクティブにしてから子フォームをアクティブにするのは簡単なのですが、
    子フォームがアクティブになっている状態で、子フォームの「ActivateParentForm」というボタンをクリックして子フォームをアクティブにする方法が分かりません。
    子フォームで親フォーム自体を取得するにはどうしたらよいのでしょうか?

    よろしくお願いします。
    2010年3月7日 12:38

回答

  • 子フォームがアクティブになっている状態で、子フォームの「ActivateParentForm」というボタンをクリックして子フォームをアクティブにする方法が分かりません。
    親フォームをアクティブにする方法、 ですよね?

    子フォームで親フォーム自体を取得するにはどうしたらよいのでしょうか?

    基本は子フォームに親フォームのインスタンスを渡すことです。子フォームのコンストラクタで渡しても良いですし、子フォームにプロパティを作成して渡しても良いです。とりあえずこれで考えてみて下さい。

    #実際には子フォームが親フォームに密に依存しないように疎結合の関係を考えるのですが、それはおいおいということで。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク yasheeki 2010年3月9日 13:26
    2010年3月7日 15:27
    モデレータ

すべての返信

  • 子フォームがアクティブになっている状態で、子フォームの「ActivateParentForm」というボタンをクリックして子フォームをアクティブにする方法が分かりません。
    親フォームをアクティブにする方法、 ですよね?

    子フォームで親フォーム自体を取得するにはどうしたらよいのでしょうか?

    基本は子フォームに親フォームのインスタンスを渡すことです。子フォームのコンストラクタで渡しても良いですし、子フォームにプロパティを作成して渡しても良いです。とりあえずこれで考えてみて下さい。

    #実際には子フォームが親フォームに密に依存しないように疎結合の関係を考えるのですが、それはおいおいということで。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク yasheeki 2010年3月9日 13:26
    2010年3月7日 15:27
    モデレータ
  • 子フォーム(ChildForm)には
    [1]
            private Form parentForm;

            public Form ParentForm
            {
                set
                {
                    parentForm = value;
                }
            }

    というプロパティを設けました。
    ついで、
    [2]
            private void showParentFormButton_Click(object sender, EventArgs e)
            {
                parentForm.Activate();
            }
    という、ボタンのクリックイベントで、親フォームをアクティブにしようと思っています。

    一方、親フォーム(ParentForm)には、
    [3]
                if (form == null)
                    form = new ChildForm();
                form.ParentForm = this;

    とすることで、親フォームを子フォームに渡そうとしています。

    こんな方法でよいのでしょうか?

    また、「子フォームが親フォームに密に依存しないように疎結合の関係を考える」というのも、どう考えたらよいものか分からないのです。

    • 編集済み yasheeki 2010年3月8日 15:39 記述間違い
    2010年3月8日 15:36
  • > こんな方法でよいのでしょうか?

    そんな感じでいいと思います。


    > また、「子フォームが親フォームに密に依存しないように疎結合の関係を考える」というのも、どう考えたらよいものか分からないのです。

    私が普段「疎結合」を考えるときは、クラスA は クラスB に依存するが、クラスB はクラスA の存在を知らなくてもいいように設計します。

    また、クラスAA が仮に クラスA の派生クラスの場合、クラスB がクラスAA を使うときは、親クラスのクラスA を使用するようにし
    派生クラスAA の存在を クラスB が知らなくてもいいようにします。 通称 「型の隠蔽」 というテクニックです。
    なんでこんな面倒なことをやるのかというと、二つのクラスが互いに密に依存しすぎていると、変更や保守が難しくなるためです。

    今回のコードを見る限りでは、Activate メソッドを呼ぶだけならば、
    具体的なクラス名ではなく、基本クラスである Form クラスをプロパティの型とするのは正解だと思います。

    時間があれば、一度以下の本を読んでみるのもいいかも知れません。

    リファクタリング―プログラムの体質改善テクニック

    デザインパターンとともに学ぶオブジェクト指向のこころ

    この二冊は、いずれも名著です。
    2010年3月8日 16:26
    モデレータ
  • また、「子フォームが親フォームに密に依存しないように疎結合の関係を考える」というのも、どう考えたらよいものか分からないのです。
    ひらぽんさんの説明の通りですが、もう少し噛み砕いて補足しておきます。
    疎結合にするとは、わかりやすく言えば特定の型を内部に持たないということです。特定の型とは、yasheekiさんなどプログラマが独自に作成した型(クラス)です。例えば、yasheekiさんは子フォームで
    private Form parentForm;
    と書かれていますが、これを
    private ParentForm parentForm;
    と書いてしまうと、子フォームはParentFormを対象とすることになり、ParentForm専用になってしまうわけです。これだと子フォームはParentForm以外を親にすることができません。またこのように子フォームはParentFormに依存していますから、ParentFormで何か変更があった場合、子フォームに影響が出る場合があります。例えばParentFormでプロパティ名を変更したとしましょう。親フォームと子フォームが同一プロジェクト内にあればコンパイル時に子フォームでコンパイルエラーが出るのでわかりますが、子フォームが仮に別のプロジェクト(dll)にあった場合は実行して初めて実行時エラーが出ます。こういうことがないように共通の契約書を作成し、お互いがそれを守るのです。それがインターフェースです。ですから、インターフェースは疎結合の場面でよく使われます。同様にイベントやデリゲートも疎結合を実現します。
    少し慣れてきたら疎結合を意識してクラスを設計するようにして下さい。疎結合を意識することはとても大切ですし、ステップアップする過程で避けて通ることはできません。

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2010年3月9日 3:03
    モデレータ
  • 書籍までご紹介いただき、ありがとうございます。

    まだ、今の私には背伸びしすぎになるかもしれませんけれど...。
    2010年3月9日 12:45
  • むむむ...。
    とはいえ、出来るだろうかという不安も感じています。
    努力次第でしょうけれど...。

    ありがとうございます。
    2010年3月9日 12:47