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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

Q&A

解決済

2回答

5587閲覧

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

negitronics

総合スコア6

C#

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

0グッド

0クリップ

投稿2015/04/21 11:56

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

lang

1using System; 2using System.Drawing; 3using System.Windows.Forms; 4namespace notepad{ 5class Program{ 6 [STAThread] 7 static void Main(){ 8 Application.EnableVisualStyles(); 9 Application.Run(new MainForm()); 10 } 11} 12class MainForm : Form{ 13 MainMenu mainMenu; 14 MenuItem find, replace; 15 Form findDialog, replaceDialog; 16 RichTextBox textBox; 17 public MainForm(){ 18 this.Size = new Size(600, 400); 19 mainMenu = new MainMenu(); 20 find = new MenuItem(){Text="検索(&F)...", Shortcut = Shortcut.CtrlF,}; 21 find.Click += (sender,e) => {findDialog.Show();}; 22 replace = new MenuItem(){Text="置換(&H)...", Shortcut = Shortcut.CtrlH,}; 23 replace.Click += (sender,e) => {replaceDialog.Show();}; 24 textBox = new RichTextBox(){Dock = DockStyle.Fill,}; 25 mainMenu.MenuItems.AddRange(new MenuItem[]{find,replace}); 26 findDialog = new EditDialog(){Text="検索"}; 27 findDialog.Controls.AddRange(new Control[]{ 28 EditDialog.targetLabel, EditDialog.targetTextBox,}); 29 replaceDialog = new EditDialog(){Text="置換"}; 30 replaceDialog .Controls.AddRange(new Control[]{ 31 EditDialog.targetLabel, EditDialog.targetTextBox,}); 32 this.Menu=mainMenu; 33 this.Controls.AddRange(new Control[]{textBox,}); 34 } 35} 36class EditDialog : Form{ 37 static public Label targetLabel; 38 static public TextBox targetTextBox; 39 static EditDialog(){ 40 EditDialog.targetLabel = new Label(){ 41 Text = "検索する文字列(&N)", 42 AutoSize = true, 43 Location = new Point(20, 30), 44 }; 45 EditDialog.targetTextBox = new TextBox(){ 46 Location = new Point(150, 30), 47 Size = new Size(100, 20), 48 }; 49 } 50 public EditDialog(){ 51 this.Size=new Size(400, 150); 52 this.Closing+=(sender,e) => {this.Hide();e.Cancel=true;}; 53 } 54} 55}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

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

投稿2015/04/21 16:20

KoichiSugiyama

総合スコア3041

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

negitronics

2015/04/21 18:20

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

0

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

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

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

lang

1using System; 2using System.Drawing; 3using System.Windows.Forms; 4 5namespace notepad 6{ 7 class Program 8 { 9 [STAThread] 10 static void Main() 11 { 12 Application.EnableVisualStyles(); 13 Application.Run(new MainForm()); 14 } 15 } 16 class MainForm : Form 17 { 18 MainMenu mainMenu; 19 MenuItem find, replace; 20 EditDialog findDialog, replaceDialog; 21 RichTextBox textBox; 22 23 public MainForm() 24 { 25 this.Size = new Size(600, 400); 26 27 find = new MenuItem() { 28 Text = "検索(&F)...", 29 Shortcut = Shortcut.CtrlF, 30 }; 31 find.Click += (sender, e) => findDialog.Show(); 32 33 replace = new MenuItem() { 34 Text = "置換(&H)...", 35 Shortcut = Shortcut.CtrlH, 36 }; 37 replace.Click += (sender, e) => replaceDialog.Show(); 38 39 textBox = new RichTextBox() { 40 Dock = DockStyle.Fill, 41 }; 42 43 mainMenu = new MainMenu(); 44 mainMenu.MenuItems.AddRange(new MenuItem[] { find, replace }); 45 46 findDialog = new EditDialog(caption:"検索"); 47 replaceDialog = new EditDialog(caption:"置換"); 48 this.Menu = mainMenu; 49 this.Controls.AddRange(new Control[] { textBox, }); 50 } 51 } 52 53 class EditDialog : Form 54 { 55 public Label targetLabel; 56 public TextBox targetTextBox; 57 58 public EditDialog(string caption) 59 { 60 this.targetLabel = new Label() 61 { 62 Text = "検索する文字列(&N)", 63 AutoSize = true, 64 Location = new Point(20, 30), 65 }; 66 this.targetTextBox = new TextBox() 67 { 68 Location = new Point(150, 30), 69 Size = new Size(100, 20), 70 }; 71 72 this.Text = caption; 73 this.Size = new Size(400, 150); 74 this.Controls.AddRange(new Control[] { 75 targetLabel, 76 targetTextBox, 77 }); 78 } 79 } 80}

すみません。自分にとって見やすいように勝手にいろいろ書き換えました。
diffってください。

投稿2015/04/21 13:23

編集2015/04/21 13:58
htsign

総合スコア870

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

negitronics

2015/04/21 18:26

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問