.netで簡易の入力フォームが無い件

# ツールを作っているときに困った話

簡単なツールとかを作っているときに、結構困ることがあります。
それは、入力フォームを作るほどではないけど、テキスト入力をしたい場合があります。

調べてみる…
「C# 入力ダイアログ」で検索するとInputBoxを使えという記事が沢山できます。
でも、これって確かVBのランタイムの機能だったのでは……
記事の中身を確認する。
やはり、VBのランタイムを参照に追加するように書かれています。
正直、入力を表示する為だけにVBのランタイムを参照したくないですよね。（変なDLLが必要になるしね）

ということで、若干雑いですが自作ダイアログを作ってみました。

## 実装コード

```InputDialog.cs
using System.Drawing;
using System.Windows.Forms;

namespace CommonSystem {
	/// <summary>入力ダイアログ</summary>
	class InputDialog {
		/// <summary>レイアウト上のマージン</summary>
		private const int Margin = 10;
		/// <summary>入力フィールドの縦幅</summary>
		private const int InputH = 25;
		/// <summary>ボタンのサイズ</summary>
		private static Size ButtonSize = new Size(70, 25);
		/// <summary>テキスト入力のダイアログを表示</summary>
		/// <param name="message">ダイアログのメッセージ</param>
		/// <param name="title">ダイアログのタイトル</param>
		/// <param name="value">入力値</param>
		/// <param name="width">windowの横幅</param>
		/// <param name="height">windowの縦幅</param>
		/// <param name="style">windowのスタイル</param>
		/// <returns>入力された文字</returns>
		public static string Show(string message, string title = "", string value = "", int width = 300, int height = 150, FormBorderStyle style = FormBorderStyle.FixedDialog){

			// formを動的に作成
			var form = new Form() {
				FormBorderStyle	= style,
				ClientSize		= new Size(width, height),
				Text			= title,
			};
			form.SuspendLayout();

			var windowPw = form.Width - width;
			var windowPh = form.Height - height;
			form.MinimumSize = new Size(windowPw + ButtonSize.Width * 2 + Margin * 3, windowPh + InputH + ButtonSize.Height + Margin * 4);

			// メッセージの作成
			var label = new Label() {
				Text			= message,
				AutoSize		= true,
				BackColor		= Color.Transparent,
				Location		= new Point(Margin, Margin),
				Width			= width - Margin * 2,
				Anchor			= AnchorStyles.Top | AnchorStyles.Left,
				TabIndex		= 1,
			};
			form.Controls.Add(label);

			// ボタンのY座標
			var buttonY = height - (ButtonSize.Height + Margin);

			// 入力フィールドの作成
			var input = new TextBox() {
				Size			= new Size(width - Margin * 2, InputH),
				Location		= new Point(Margin, buttonY - InputH),
				Text			= value,
				Anchor			= AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right,
				TabIndex		= 2,
			};
			form.Controls.Add(input);

			// ok
			var ok = new Button() {
				DialogResult	= DialogResult.OK,
				Size			= ButtonSize,
				Text			= "&OK",
				Location		= new Point(width - ButtonSize.Width * 2 - Margin * 2, buttonY),
				Anchor			= AnchorStyles.Bottom | AnchorStyles.Right,
				TabIndex		= 3,
			};
			form.Controls.Add(ok);
			form.AcceptButton = ok;

			// cancel(okボタンの位置からマージン分を右に移動させる)
			var cancel = new Button() {
				DialogResult	= DialogResult.Cancel,
				Size			= ButtonSize,
				Text			= "&Cancel",
				Location		= ok.Location + new Size(ButtonSize.Width + Margin, 0),
				Anchor			= AnchorStyles.Bottom | AnchorStyles.Right,
				TabIndex		= 4,
			};
			form.Controls.Add(cancel);
			form.CancelButton = cancel;

			form.ResumeLayout(false);
			form.PerformLayout();

			// dialogの表示
			var result = form.ShowDialog();
			// 結果から戻り値を決定
			return (result == DialogResult.OK) ? input.Text : null;
		}
	}
}
```
そこそこ、新しい文法で書いているところもあるので古いC#バージョンで使いたい場合は適宜修正してみてください。


## 使い方

```C#
var debugID = InputDialog.Show("デバッグ用IDを指定してください");
```

## 表示サンプル

![InputDialog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322199/1e8384c9-20b5-24b8-c109-520a069c8a7e.png)

必要ないかもしれませんが、WindowStyleを指定できるので可変ウインドウでも一応使えます。
ただし、アイコンがデフォルトになってしますのであれです。