.NET Core 3.0 で Windows フォームアプリケーションを作るには、.NET Framework と同じようにまずプロジェクト(ソリューション)を作ります。
.NET Core 3.0 用のフォームのデザイナがないことが話題ですが、大丈夫です。対策となる大きく2つの手法をこの記事で書いています。
対策となる2種類の手法
- コードビハインドで配置する
- デザイナーが忘れられない!
■ プロジェクトの作成
対策は後述するので、まずはプロジェクトを作成して行きます。
プロジェクト作成コマンド
dotnet new winforms -n winformapp
この例では、 -n でプロジェクト名を winformapp と指定しています。プロジェクト名のフォルダが作られ、その中にプロジェクトが作成されています。
プロジェクトの場所へフォルダを移動します。
cd winformapp
ただ、ここまでの手順ではソリューションは作られていないのでソリューションも作っておきましょう。
ソリューション作成コマンド
dotnet new sln
winformapp.sln ファイルが作成されますが、まだプロジェクトが含まれていないのでプロジェクトをソリューションに追加します。
dotnet sln add winformapp.csproj
これでソリューションに winformapp プロジェクトが追加されました。
作成したソリューションを Visual Studio 2019 Preview で開きます。
- Visual Studio 2019 Preview を起動します
- [ プロジェクトやソリューションを開く ] から作成した winformapp.sln を選択します。
■ デバッグ実行
作成した winformapp プロジェクトはそのまま実行可能です。いったん実行してみましょう。
ここから色々とコントロールを配置してアプリを作って行くわけですが、残念ながらコントロールを配置するためのデザイナーが用意されていません。
しかし、まだあきらめるタイミングではありません。Windows フォームアプリケーションはデザイナーがなければ作らないというものではありません。
■ パターン1 コードビハインドで配置する
コードビハインドでコントロールを new して配置して行けば簡単にコントロールを配置できます。
Form1.cs にコードを書いていきます。
using System; using System.Drawing; using System.Windows.Forms; namespace winformapp { public partial class Form1 : Form { // 配置したコントロールを保持するメンバー Panel panel; TextBox textBox; Button button; public Form1() { InitializeComponent(); // 自分でコントロールを生成し配置する CreateAndLayoutControls(); } // 自分でコントロールを生成し配置する void CreateAndLayoutControls() { // パネルを生成し Form の上に乗せる(背景色はアジュール) this.Controls.Add(panel = new Panel { Location = new Point(10, 10), BackColor = Color.Azure, Size = new Size(300,100), }); // テキストボックスを生成しパネルの上に乗せる panel.Controls.Add(textBox = new TextBox { Location = new Point(5,0), Size = new Size(200,22), }); // ボタンを生成しパネルの上に乗せる(背景色はクリムゾン) panel.Controls.Add(button = new Button { Location = new Point(5, 23), Size = new Size(200, 22), Text = "ボタン", BackColor = Color.Crimson, }); // ボタンクリック時のイベントハンドラを設定する button.Click += Button_Click; // パネルが表示されるよう最前面に移動 panel.BringToFront(); } // ボタンクリックのイベントハンドラ private void Button_Click(object sender, EventArgs e) { // テキストボックスに入力されている文字列をメッセージボックスで表示 MessageBox.Show(textBox.Text); } private void buttonExit_Click(object sender, EventArgs e) { Application.Exit(); } } }
ポイントは次のパネル生成部分のコードです。
// パネルを生成し Form の上に乗せる(背景色はアジュール) this.Controls.Add(panel = new Panel { Location = new Point(10, 10), BackColor = Color.Azure, Size = new Size(300,100), });
Windows フォームのコントロールは当たり前と言えば当たり前ですが、new してインスタンス化できます。つまり普通に new して Form に Add してやれば画面に表示されます。
あとはこれを配置したいコントロール分繰り返せば OK です。簡単ですね。
他のポイントとしては
// 配置したコントロールを保持するメンバー
Panel panel;
TextBox textBox;
Button button;
というメンバー宣言でしょうか。デザイナーで配置した場合と同じように、コードビハインドでコントロールを操作するためにメンバーにコントロールのインスタンスを保持しています。これはデザイナーで配置した場合もデザイナーが同様のコードを自動で作成してくれているものです。
実行
実行するとこのように、パネルの上にテキストボックスとボタンが置かれ、ボタンクリックのイベントも動作します。
■ パターン2 デザイナーと同じがいい!
コードでコントロールを配置するのに違和感がありどうしてもデザイナーがいいという方も大丈夫です。Windows フォームアプリケーションのデザイナーが生成するコードはシンプルなので誰でも簡単に書けます。
まずは、テンプレートで生まれたコードを見てみましょう。
namespace winformapp { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.buttonExit = new System.Windows.Forms.Button(); this.SuspendLayout(); // // label1 // this.label1.Dock = System.Windows.Forms.DockStyle.Fill; this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 28.125F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.label1.Location = new System.Drawing.Point(0, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(800, 376); this.label1.TabIndex = 1; this.label1.Text = "Hello .NET Core!"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // buttonExit // this.buttonExit.Dock = System.Windows.Forms.DockStyle.Bottom; this.buttonExit.Location = new System.Drawing.Point(0, 376); this.buttonExit.Name = "buttonExit"; this.buttonExit.Size = new System.Drawing.Size(800, 74); this.buttonExit.TabIndex = 1; this.buttonExit.Text = "E&xit"; this.buttonExit.UseVisualStyleBackColor = true; this.buttonExit.Click += new System.EventHandler(this.buttonExit_Click); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 450); this.Controls.Add(this.label1); this.Controls.Add(this.buttonExit); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion private System.Windows.Forms.Label label1; private System.Windows.Forms.Button buttonExit; } }
とても簡単ですね。大きく4つの区切りがあります。
コントロールのインスタンス保持用のメンバー宣言
一番下の部分です。ここでコントロールのインスタンスを保持するメンバーの宣言をしています。コントロールを追加したい場合、まずはここにメンバーを追加すれば良いでしょう。簡単ですね。
private System.Windows.Forms.Label label1; private System.Windows.Forms.Button buttonExit;
コントロールのインスタンス化
戻ってコードの上の方 InitializeComponent メソッドの最初の部分です。ここで、コントロールのインスタンスを生成しています。コントロールを追加した良い場合、ここでインスタンス化すれば良いでしょう。簡単ですね。
this.label1 = new System.Windows.Forms.Label(); this.buttonExit = new System.Windows.Forms.Button();
コントロールのプロパティ
次の部分はコントロールのプロパティを設定する部分です。コントロール全てのプロパティの初期値を順に設定しています。コントロールのプロパティはここで設定すれば良いでしょう。簡単ですね。
// // label1 // this.label1.Dock = System.Windows.Forms.DockStyle.Fill; this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 28.125F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.label1.Location = new System.Drawing.Point(0, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(800, 376); this.label1.TabIndex = 1; this.label1.Text = "Hello .NET Core!"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
コントロールの Add
次の部分は Form の設定をしている部分です。Form のプロパティの設定とコントロールの追加をしています。フォームへのコントロールの追加はここで行えばいいでしょう。簡単ですね。
// // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 450); this.Controls.Add(this.label1); this.Controls.Add(this.buttonExit); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false);
コントロールを配置する
Form1.Designer.cs を編集してコントロールを配置してみます。
namespace winformapp { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.buttonExit = new System.Windows.Forms.Button(); this.panel = new System.Windows.Forms.Panel(); this.textBox = new System.Windows.Forms.TextBox(); this.button = new System.Windows.Forms.Button(); this.panel.SuspendLayout(); this.SuspendLayout(); // // label1 // this.label1.Dock = System.Windows.Forms.DockStyle.Fill; this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 28.125F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.label1.Location = new System.Drawing.Point(0, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(800, 376); this.label1.TabIndex = 1; this.label1.Text = "Hello .NET Core!"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // buttonExit // this.buttonExit.Dock = System.Windows.Forms.DockStyle.Bottom; this.buttonExit.Location = new System.Drawing.Point(0, 376); this.buttonExit.Name = "buttonExit"; this.buttonExit.Size = new System.Drawing.Size(800, 74); this.buttonExit.TabIndex = 1; this.buttonExit.Text = "E&xit"; this.buttonExit.UseVisualStyleBackColor = true; this.buttonExit.Click += new System.EventHandler(this.buttonExit_Click); // // panel // this.panel.Controls.Add(this.textBox); this.panel.Controls.Add(this.button); this.panel.BackColor = System.Drawing.Color.Azure; this.panel.Location = new System.Drawing.Point(10, 10); this.panel.Size = new System.Drawing.Size(300, 100); // // textBox // this.textBox.Location = new System.Drawing.Point(5, 0); this.textBox.Size = new System.Drawing.Size(200, 22); // // button // this.button.BackColor = System.Drawing.Color.Crimson; this.button.Location = new System.Drawing.Point(5, 23); this.button.Size = new System.Drawing.Size(200, 22); this.button.Text = "ボタン"; this.button.Click += new System.EventHandler(this.Button_Click); // // Form1 // //this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 450); this.Controls.Add(this.panel); this.Controls.Add(this.label1); this.Controls.Add(this.buttonExit); this.Name = "Form1"; this.Text = "Form1"; this.panel.ResumeLayout(false); this.panel.PerformLayout(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Label label1; private System.Windows.Forms.Button buttonExit; private System.Windows.Forms.Panel panel; private System.Windows.Forms.TextBox textBox; private System.Windows.Forms.Button button; } }
こんな感じで書けば、デザイナーなしでもコントロールを配置できます。簡単ですね。
是非チャレンジしてみてください。