none
FORMを継承したabstructなクラス生成 RRS feed

  • 質問

  • お世話になっております。
    相談に乗って頂きたいのですが

    ある、子フォームに
    追加ボタン、削除ボタンを配置し
    ボタンクリック時の処理を
    派生クラスで処理するように
    以下のようなクラスを生成しました。

    public abstract partial class Form_universal : Form
    {
        public Form_universal()
        {
            InitializeComponent();
        }
       
        protected abstract void addData();
        protected abstract void removeData();
       
        private void button1_Click(object sender, EventArgs e)
        {
            addData();
        }
       
        private void button2_Click(object sender, EventArgs e)
        {
            removeData();
        }
    }

    とし、
    「新しい項目」から「クラス」を選択し、

    ファイル名をForm_TEST.csとして

    public partial class Form_TEST : Form_universal
    {
        public Form_TEST(){}
       
        protected override void  addData()       { MessageBox.Show( "add" ); }
        protected override void  removeData() { MessageBox.Show( "del" );  }
    }

    のようなクラスを作ると実行は出来るのですが
    ソリューションエクスプローラーからForm_TEST.csをクリックして開こうとすると


    デザイナの読み込み時に 1 つ以上のエラーが発生しました。
    エラーは以下に一覧表示されます。
    コードの変更が必要なエラーもありますが、プロジェクトを再度ビルドすると解決できるエラーもあります。

    デザイナは型 'XXXXX.Form_universal' のインスタンスを作成しなければなりませんが、
    型が abstract として宣言されているため、作成できませんでした。

    と言ったエラーが出てしまいます。
    右クリックから「コードの表示」でソースは見れます。

    そもそも、こう言った事はやるべきではないのでしょうか?

    2009年6月7日 7:18

回答

  • こんにちは、りばてぃです。

    とりあえず解決に向かっているようなので余談として・・・

    VSはデザイナを開くときに継承元コントロール(Formも同様)のインスタンスを作成して、
    自コントロールのデザイン設定を上からかぶせて表示させる
    というような動きをしています。
    # ニュアンスとしてこんな感じというだけで正確な表現ではないかもしれません。

    このため、継承元がabstractなどでインスタンス生成ができないと
    デザイン時にエラーとなってしまうので、
    現実的には継承元コントロールをabstractにすることはできないということになってしまっています。

    というわけで Azuleanさん が回答されているようにvirtualを利用した方法が現実解になってきます。
    • 回答としてマーク zilch_1975 2009年6月8日 4:20
    2009年6月8日 2:21
  • 「新しい項目」から「クラス」を選択し、

    ファイル名をForm_TEST.csとして

    public partial class Form_TEST : Form_universal
    {
        public Form_TEST(){}
       
        protected override void  addData()       { MessageBox.Show( "add" ); }
        protected override void  removeData() { MessageBox.Show( "del" );  }
    }

    のようなクラスを作ると実行は出来るのですが

    ああ、ここの操作かな?
    フォームから派生するクラスを作る際は、「クラス」として作るのではなく、「継承されたWindowsフォーム」とかそんな名前のテンプレートを選択して追加することが一般的です。
    このようにすると、継承元から引き継いだコントロールも表示されるデザイナが表示できるようになります。


    今は、デザイナに必要なコードがないことから、エラーになっているのかな?
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク zilch_1975 2009年6月8日 4:19
    2009年6月7日 15:14
    モデレータ

すべての返信

  • Form_universalの例が変でした。
    これだと
    フォームを継承してコントロールへのイベントを派生クラスで処理すれば?
    となってしまいますね。

    修正しますと

    public abstract partial class Form_universal : Form
    {
            ・    
            ・    
        protected abstract void addData();
        protected abstract void removeData();
       
        private void button1_Click(object sender, EventArgs e)
        {
           // ある共通処理を行う
            addData();
        }
       
        private void button2_Click(object sender, EventArgs e)
        {
           // ある共通処理を行う
            removeData();
        }

        private void 共通処理()
        {
        }
    }

    と言う処理が必須となります。

    2009年6月7日 8:03
  • どうしてもabstractにしないと駄目なのでしょうか?
    基底クラス側をvirtual指定で何もしない関数にすれば、とりあえずは回避できるかもしれません。


    # デザイナで操作するクラスは、あまり凝ったことをしない方が良いと思っています。
    # ジェネリック周りでも表示できなくなったりすることがあったはず…。


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年6月7日 12:03
    モデレータ
  • Azuleanさん、いつもご返答有難う御座います。

    基底クラス側をvirtualにして
    派生クラス側でoverrideしたのですが
    派生クラス側のソースをダブルクリックするとどうようにエラーが発生しました。
    ソースを開くでは開くことが出来ます。
    2009年6月7日 15:10
  • 「新しい項目」から「クラス」を選択し、

    ファイル名をForm_TEST.csとして

    public partial class Form_TEST : Form_universal
    {
        public Form_TEST(){}
       
        protected override void  addData()       { MessageBox.Show( "add" ); }
        protected override void  removeData() { MessageBox.Show( "del" );  }
    }

    のようなクラスを作ると実行は出来るのですが

    ああ、ここの操作かな?
    フォームから派生するクラスを作る際は、「クラス」として作るのではなく、「継承されたWindowsフォーム」とかそんな名前のテンプレートを選択して追加することが一般的です。
    このようにすると、継承元から引き継いだコントロールも表示されるデザイナが表示できるようになります。


    今は、デザイナに必要なコードがないことから、エラーになっているのかな?
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク zilch_1975 2009年6月8日 4:19
    2009年6月7日 15:14
    モデレータ
  • こんにちは、りばてぃです。

    とりあえず解決に向かっているようなので余談として・・・

    VSはデザイナを開くときに継承元コントロール(Formも同様)のインスタンスを作成して、
    自コントロールのデザイン設定を上からかぶせて表示させる
    というような動きをしています。
    # ニュアンスとしてこんな感じというだけで正確な表現ではないかもしれません。

    このため、継承元がabstractなどでインスタンス生成ができないと
    デザイン時にエラーとなってしまうので、
    現実的には継承元コントロールをabstractにすることはできないということになってしまっています。

    というわけで Azuleanさん が回答されているようにvirtualを利用した方法が現実解になってきます。
    • 回答としてマーク zilch_1975 2009年6月8日 4:20
    2009年6月8日 2:21
  • Azuleanさん

    有難う御座いました。
    「継承されたフォーム」
    で作成するとうまく行きました!
    有難う御座いました。

    2009年6月8日 4:18
  • りばてぃさん

    継承元がabstractだと問題があるのが分かりました。
    有難う御座いました。
    2009年6月8日 4:20