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

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

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

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

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

Q&A

解決済

4回答

4705閲覧

クラス内でボタンを配置したいのですが可能でしょうか?

fender0131

総合スコア121

C#

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

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

0グッド

0クリップ

投稿2015/12/11 09:39

いつも大変お世話になっております。

以下のプログラムの時、クラス内でボタンを配置することは可能でしょうか?
今ですとボタンを配置するのに、Form1でfor文を使わないといけないので、スムーズではないように思えます・・・

● Form1

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace testA { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Class1 C = new Class1(); C.button(); for (int i = 0; i < 2; i++) { this.Controls.Add(Class1.bt[i]); // ここではなく } } } }

● Class1

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace testA { class Class1 { public static Button[] bt = new Button[2]; public void button() { for (int i = 0; i < 2; i++) { bt[i] = new Button(); bt[i].Size = new Size(100, 100); bt[i].Location = new Point(100*(i+1), 100*(i+1)); bt[i].Font = new Font("Arial", 10); // Controls.Add(bt[i]); // ここで配置したい } } } }

お手数おかけして申し訳ございませんが、どなた様かご指導ご鞭撻の程よろしくお願い致します。

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

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

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

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

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

guest

回答4

0

単に処理を分割したいだけなら別クラスを作るのは例えば一か月月後に触ったときに訳が分からなくなってしまうので止めたほうが良いです

フォームはpartialで定義されているので、ソースファイルを一つ作ってそっちで

C#

1public partial class Form1 : Form 2{ 3 private void CreateButton() 4 { 5 // ここにボタンを作る処理を入れてください 6 } 7}

という形にしたほうが良いですよ
partialは一つのクラス定義を複数のファイルに分割できるようにするために用意されたキーワードです
参照:https://msdn.microsoft.com/ja-jp/library/wbx7zzdd.aspx?f=255&MSPPError=-2147217396
別クラスでということだったので何かの処理に付随したボタンを用意しているものだと解釈して前回は返答しましたが、単にソースが長くなったから分割したいという理由であるなら別クラスで吐き出すのではなくてpartialで分割すべきです
内部的にもオーバーヘッドが増えてリソースも処理も無駄に増えてしまうデメリットしかありませんし、作る際にものちのちご自身および他の人が見た際に別クラス化しているから単に処理を分割しただけとは考えずにフォームそのものとは全く関係のないものだから別クラス化していると考えますのでややこしくなってしまいます
ちなみに自分で作ったものだから大丈夫だと思っているかもしれませんが、それなりに時間が経つと忘れます
なので間違いなく後々修正する際にも意味が分からなくなって困ると思いますし、仮に現在作成しているプログラムは練習で二度と触らないとしても今回で別クラス化をするとした場合は今後も同じようにしてしまうと思いますのでのちのち困ることになります
なのでpartialで行うべきです

投稿2015/12/14 05:37

len_souko

総合スコア1348

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

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

fender0131

2015/12/14 06:04

本当に貴重なご意見ありがとうございます。 非常にわかりやすい説明で、初心者の自分でも納得できました。 「partial」という概念を持ち合わせていなかったせいもあり、あのような考えしか思いつきませんでした。 まだまだ駆け出しなもので目先だけの処理に目が行ってしまい、後の事まで考えが行っていませんでした・・・ len_souko様のお答えを元にもう一度考え直してみようと思います。 本当にありがとうございます。
guest

0

そもそもForm1,Class1でなにをしようとしている(なにがしたい)のかが、あやふやになっているんじゃないですか?

Class1で

  • 何らかの設定を行ったボタンを生成したいのならボタンが返り値になる

ようにすべきですし、

  • 特定のボタンの設定を変更したいのであれば変更するボタンを引数で与える

ようにすべきだと思います

あとコードでは複数のボタンに対して処理したいようなので

  • 都度ばらばらのボタンを返す
  • 生成したボタンをひとかたまりにして返す(何らかのコンテナに入れて返す)

によって書きべきコードが変わってくるのでは?

投稿2015/12/11 20:53

dojikko

総合スコア3939

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

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

fender0131

2015/12/14 05:16

お答えありがとうございます。 Form1でボタンを作成していたのですが、ボタン作成するソースコードが長くなり、 Form1のプログラムソースが見づらくなってしまったので、クラスに渡し見やすくしようとしております。 貴重なご意見ありがとうございます。 もう一度考えをまとめてみようと思います。
guest

0

FlowLayoutPanelやTableLayoutPanelを引数としてクラスの内部でボタンを追加していくのはどうでしょう?

これならば追加したものが何であれ後からアクセスすることも可能ですし、追加されたものが何であるかを意識する必要はありません

ちなみに以下のコードは動作確認どころかコンパイルの確認すら取っていませんので動かない可能性があります

C#

1 2public partial class Form1 : Form 3{ 4 public Form1() 5 { 6 InitializeComponent(); 7 } 8 9 private void Form1_Load(object sender, EventArgs e) 10 { 11 Class1 C = new Class1(); 12 13 // Panel1はこのクラスで作ったボタンを表示させたい場所をフォーム上にFlowLayoutPanelやTableLayoutPanelを事前に配置したものとしておきます 14 C.button(Panel1); 15 } 16 17} 18 19 20class Class1 21{ 22 // FlowLayoutPanelのところは実際にやりたい配置に合わせたコンテナを選んでください 23 public void button(FlowLayoutPanel targetPanel) 24 { 25 // 確認してないけど、ここで多分targetPanel.Controlsの一つ一つを削除していったほうが良いと思う 26 foreach(Control item in targetPanel.Controls) 27 { 28 item.Dispose(); 29 } 30 // Clear()だけでリソースも解放されるなら上の処理は不要です 31 targetPanel.Controls.Clear(); 32 33 for (int i = 0; i < 2; i++) 34 { 35 var bt = new Button(); 36 bt.Size = new Size(100, 100); 37 bt.Font = new Font("Arial", 10); 38 targetPanel.Controls.Add(bt); 39 } 40 } 41}

投稿2015/12/11 13:26

編集2015/12/11 13:31
len_souko

総合スコア1348

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

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

fender0131

2015/12/14 05:20

お答えありがとうございます。 貴重なご意見ありがとうございます。 FlowLayoutPanelやTableLayoutPanelを使ったことがなかったので、これを機に調べてみようかと思います。
guest

0

ベストアンサー

こんにちは。

こうか、

C#

1public partial class Form1 : Form 2{ 3 public Form1() 4 { 5 InitializeComponent(); 6 } 7 8 private void Form1_Load(object sender, EventArgs e) 9 { 10 Class1 C = new Class1(); 11 C.button(this.Controls); 12 } 13} 14 15class Class1 16{ 17 public void button(System.Windows.Forms.Control.ControlCollection controls) 18 { 19 for (int i = 0; i < 2; i++) 20 { 21 var bt = new Button(); 22 bt.Size = new Size(100, 100); 23 bt.Location = new Point(100 * (i + 1), 100 * (i + 1)); 24 bt.Font = new Font("Arial", 10); 25 controls.Add(bt); 26 } 27 } 28}

こうですかね。

C#

1public partial class Form1 : Form 2{ 3 public Form1() 4 { 5 InitializeComponent(); 6 } 7 8 private void Form1_Load(object sender, EventArgs e) 9 { 10 Class1 C = new Class1(); 11 this.Controls.AddRange(C.button()); 12 } 13} 14 15class Class1 16{ 17 public Button[] button() 18 { 19 Button[] bt = new Button[2]; 20 for (int i = 0; i < 2; i++) 21 { 22 bt[i] = new Button(); 23 bt[i].Size = new Size(100, 100); 24 bt[i].Location = new Point(100 * (i + 1), 100 * (i + 1)); 25 bt[i].Font = new Font("Arial", 10); 26 } 27 return bt; 28 } 29}

投稿2015/12/11 10:21

Tak1wa

総合スコア4791

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

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

fender0131

2015/12/14 05:21

お答えありがとうございました。 「this.Controls」を引数として渡してあげればよかったのですね。 問題解決いたしました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問