質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • C#

    7380questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

[C#]異なるダイアログで部品を共有したいのですが

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,589

negitronics

score 1

メモ帳のようなアプリを作っているのですが、検索ダイアログと置換ダイアログで共通する部分があり、(検索文字列のテキストボックス、大文字小文字区別のためのチェックボックスなど)共有化したいと考えました。そこで、自作のダイアログクラスに静的な変数として各種のコントロールを定義して、インスタンス生成後、各自で必要な部品を追加するようにしました。
以下のコードですとコンパイルはうまくいくのですが、検索ダイアログに何も表示されず、置換ダイアログだけにコントロールが配置されてしまいます。staticを使うやり方が間違っているのでしょうか?解決策をご教示ください。

using System;
using System.Drawing;
using System.Windows.Forms;
namespace notepad{
class Program{
    [STAThread]
    static void Main(){
        Application.EnableVisualStyles();
        Application.Run(new MainForm());
    }
}
class MainForm : Form{
    MainMenu mainMenu;
    MenuItem find, replace;
    Form findDialog, replaceDialog;
    RichTextBox textBox;
    public MainForm(){
        this.Size = new Size(600, 400);
        mainMenu = new MainMenu();
        find = new MenuItem(){Text="検索(&F)...", Shortcut  =  Shortcut.CtrlF,};
        find.Click += (sender,e) => {findDialog.Show();};
        replace = new MenuItem(){Text="置換(&H)...", Shortcut  =  Shortcut.CtrlH,};
        replace.Click += (sender,e) => {replaceDialog.Show();};
        textBox = new RichTextBox(){Dock = DockStyle.Fill,};
        mainMenu.MenuItems.AddRange(new MenuItem[]{find,replace});
        findDialog = new EditDialog(){Text="検索"};
        findDialog.Controls.AddRange(new Control[]{
        EditDialog.targetLabel, EditDialog.targetTextBox,});
        replaceDialog = new EditDialog(){Text="置換"};
        replaceDialog .Controls.AddRange(new Control[]{
        EditDialog.targetLabel, EditDialog.targetTextBox,});
        this.Menu=mainMenu;
        this.Controls.AddRange(new Control[]{textBox,});
    }
}
class EditDialog : Form{
  static public Label targetLabel;
  static public TextBox targetTextBox;
  static EditDialog(){
        EditDialog.targetLabel = new Label(){
         Text = "検索する文字列(&N)",
          AutoSize = true,
          Location = new Point(20, 30),
        };
        EditDialog.targetTextBox = new TextBox(){
            Location = new Point(150, 30),
            Size = new Size(100, 20),
        };
    }
    public EditDialog(){
        this.Size=new Size(400, 150);
        this.Closing+=(sender,e) => {this.Hide();e.Cancel=true;};
    }
}
}

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

最近似たようなことをやりましたが、共通部分の部品のみ持っているフォームを基底クラスとしてそれを継承して別々のフォームを作る、という方法をとりました。その際にリンク先の@ITの記事を参考にしました。こういう解決方法はどうでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/04/22 03:20

    staticをやめて継承を利用したらうまくいきました。確かにこちらのほうがシンプルですね。

    キャンセル

0

こういう実装はしたことがないため憶測になってしまうのですが、インスタンスが共有化されるためにもう一方に貼り付けると元の場所から剥がれ落ちる、みたいなことかと。
あくまでインスタンスは一つなので。

staticは扱いが難しい気がしているので、個人的にあまり使わない方がいいと思っています。
使うときはSingletonパターンくらいですかね…。

staticメソッドは別です。割と使います。
拡張メソッドもstaticクラスのstaticメソッドですしね。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace notepad
{
    class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new MainForm());
        }
    }
    class MainForm : Form
    {
        MainMenu mainMenu;
        MenuItem find, replace;
        EditDialog findDialog, replaceDialog;
        RichTextBox textBox;

        public MainForm()
        {
            this.Size = new Size(600, 400);

            find = new MenuItem() { 
                Text = "検索(&F)...",
                Shortcut = Shortcut.CtrlF, 
            };
            find.Click += (sender, e) => findDialog.Show();

            replace = new MenuItem() { 
                Text = "置換(&H)...", 
                Shortcut = Shortcut.CtrlH,
            };
            replace.Click += (sender, e) => replaceDialog.Show();

            textBox = new RichTextBox() {
                Dock = DockStyle.Fill,
            };

            mainMenu = new MainMenu();
            mainMenu.MenuItems.AddRange(new MenuItem[] { find, replace });

            findDialog = new EditDialog(caption:"検索");
            replaceDialog = new EditDialog(caption:"置換");
            this.Menu = mainMenu;
            this.Controls.AddRange(new Control[] { textBox, });
        }
    }

    class EditDialog : Form
    {
        public Label targetLabel;
        public TextBox targetTextBox;

        public EditDialog(string caption)
        {
            this.targetLabel = new Label()
            {
                Text = "検索する文字列(&N)",
                AutoSize = true,
                Location = new Point(20, 30),
            };
            this.targetTextBox = new TextBox()
            {
                Location = new Point(150, 30),
                Size = new Size(100, 20),
            };

            this.Text = caption;
            this.Size = new Size(400, 150);
            this.Controls.AddRange(new Control[] { 
                targetLabel,
                targetTextBox,
            });
        }
    }
}
すみません。自分にとって見やすいように勝手にいろいろ書き換えました。
diffってください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/04/22 03:26

    インスタンスが剥がれ落ちる、という考えは思いつきませんでしたが、確かにそのようなことが起きているようです。ダイアログクラスをインスタンス化する順番を変えて、検索ダイアログを後からインスタンス化すると、検索ダイアログ側にコントロールが表示されるようになりました。今回はstaticをやめてみますが、個人的にこの挙動の根拠を調べたいと思います。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    書き方はどちらがよいでしょうか

    VisualStudioを使わないでC#を書くのは非効率、変なことなのかもしれませんが、Windowsフォームアプリケーションを手書きで1から書くとしたら、次のどちらの書き方がよい

  • 解決済

    C#.netでフォームの遷移

    前提・実現したいことC#.netでフォームの遷移を行いたいのですが、新しいフォームが開いてしまい困っています。 新しいウィンドウではなく同じウィンドウで違うフォームを開くことはでき

  • 解決済

    Taskが実行されません。

    ネットで、ThreadよりTaskを使ったほうが良いという記事を見て、コピペで使ってみましたが、動きません。 MSDNを見ても、同じようなコードがあったのでこれでいいのかなーと思

  • 解決済

    C#でTabPageにDataGridViewを表示させ、DataGridViewのサイズがClie...

    C#でTabPageにDataGridViewを表示させ、DataGridViewのサイズがClientSizeを超える場合に、スクロールバーを表示したいのですが表示されません.

  • 解決済

    VBScriptのボタン

    vbscriptをつかってシャットダウンをさせたいと思っています。 現在のソースはこちら Msg = MsgBox("シャットダウンしますか?", vbYesNo + 

  • 解決済

    CS103:現在のコンテキスト内に存在しません。

    C# を現在VisualStudio を使わずに書いています。 プロジェクトには以下のファイルがあります。 main.cs Form1.cs ←どちらもクラス名は同

  • 解決済

    C# ListBoxのダブルクリックイベントの取得

    C#でListBoxに表示された項目をダブルクリックすると、 別のListBoxに表示させるような処理をしたいです。 ツールボックス→プロパティ→MouseDoubleClickと

  • 解決済

    C# 手動でWindowsフォーム作成

    ぽとペタ開発は楽でいいのですが、手動で書く場合はどのようにしたらいいのかと思い実践しています。 わからないのが、配置したボタンのイベントハンドラで配置してあるラベルのTextプ

同じタグがついた質問を見る

  • C#

    7380questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。