テキストボックスにテキストが入力されていない状態の時に、入力内容や入力例が表示されていると、アプリケーションを使うユーザーはテキストボックスに入力するテキストをスムーズに入力することができます。このようなナビゲーション機能は、ユーザービリティを向上させます。

今回は、Windowsフォームアプリケーションのテキストボックスに、プレースホルダー(初期表示文言)を設定する方法を紹介します。
目次
プレースホルダーの表示 (.NET Core 3.0以上)
テキストボックスにテキストが未入力でフォーカスされていない場合にプレースホルダー(初期表示文言)を表示するするには、System.Windows.Forms名前空間にあるTextBoxクラスのPlaceholderTextプロパティを使用します。
PlaceholderTextプロパティ
フォームに「textBox1」という名前のテキストボックスを配置し、コードエディタを表示して以下のコードを入力します。
| 
					 1 2  | 
						// プレースホルダーのテキストを設定 this.textBox1.PlaceholderText = HorizontalAlignment.Left;  | 
					
上記のコードはフォームのコンストラクタ内や、フォームのロードイベント(Form.Load)メソッド内、またはフォームのオンロード(OnLoad)メソッドをオーバーライドしたメソッド内に記述することで、フォームの起動時に設定することができます。
Windowsフォームデザイナー
通常版のVisual Studioでは、.NET CoreのWindowsフォームデザイナーが表示されませんが、Visual Studioのプレビュー版をインストールすれば表示できます。(2020年4月時点)
プレビュー版のインストールと、.NET CoreのWindowsフォームデザイナーを表示する方法については、以下の記事を参照してください。
Windowsフォームデザイナーを表示します。

フォームにテキストボックスを配置して選択します。

デザイナーのプロパティグリッドにある「PlaceholderText」プロパティにプレースホルダーとして表示するテキストを入力します。

PlaceholderTextプロパティ入力したテキストがプレースホルダーのテキストとして表示されます。

サンプルプログラム (.NET Core 3.0以上)
テキストボックスの文字の揃え位置を設定するサンプルプログラムを作成します。
ユーザーインターフェース
フォームには、プレースホルダーのテキストを表示するテキストボックス(textBox1)、プレースホルダ―のテキストを入力するテキストボックス(textBox2)、右揃えに設定するテキストボックス(button1)を配置します。

ソースコード
ボタンをクリックした時に、指定されたテキストをプレースホルダーのテキストに設定する処理を記述します。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34  | 
						using System; using System.Windows.Forms; namespace WindowsFormsApp1 {     public partial class Form1 : Form     {         // コンストラクタ         public Form1()         {             InitializeComponent();             // ボタンのクリックイベント             this.button1.Click += Button1_Click;         }         // ボタンクリック時のイベントメソッド         private void Button1_Click(object sender, EventArgs e)         {             try             {                 // プレースホルダ―のテキストを取得                 string placeHolderText = this.textBox2.Text;                 // プレースホルダ―のテキストを設定                 this.textBox1.PlaceholderText = placeHolderText;             }             catch (Exception ex)             {                 MessageBox.Show(ex.Message);             }         }     } }  | 
					
プログラムの実行
プロジェクトをビルドして実行(デバッグ)してフォームを表示します。

テキストボックスに文字列を入力して揃え位置を確認します。

ボタンをクリックしてプレースホルダーのテキストを設定します。

テキストボックスにプレースホルダーのテキストが表示されます。
プレースホルダーの表示 (.NET Framework)
.NET FrameworkのWindowsフォームのTextBoxコントロールには、PlaceholderTextプロパティがありません。
ですので、.NET Coreのように簡単にプレースホルダーのテキストを設定することはできません。
.NET Core のTextBoxコントロールのPlaceholderTextプロパティと同様に設定して使うことができるように、テキストボックスにプロパティを追加して機能拡張したカスタムコントロールを作成します。
ソースコード
PlaceholderTextプロパティを追加したカスタムコントロールの実装例を以下に示します。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99  | 
						using System; using System.Drawing; using System.Windows.Forms; namespace Johobase.Example {     public partial class PlaceholderTextBox : TextBox     {         // コンストラクタ         public PlaceholderTextBox()         {             this._placeholderText = "";             this._placeholderColor = Color.Empty;         }         #region プロパティ         // プレースホルダーのテキスト         private string _placeholderText;         public string PlaceholderText         {             get             {                 return this._placeholderText;             }             set             {                 this._placeholderText = value;                 this.Refresh();             }         }         // プレースホルダーの色         private Color _placeholderColor;         public Color PlaceholderColor         {             get             {                 return this._placeholderColor;             }             set             {                 this._placeholderColor = value;                 this.Refresh();             }         }         #endregion         // ペイントを表す定数         private const int WM_PAINT = 0x000f; // 15         // WndProcMethodのオーバーライド         protected override void WndProc(ref Message message)         {             base.WndProc(ref message);             if (message.Msg == WM_PAINT)             {                 if (this.Enabled &&                     !this.ReadOnly &&                     !this.Focused &&                     string.IsNullOrEmpty(this.Text) &&                     !string.IsNullOrEmpty(this._placeholderText))                 {                     // テキストボックスが入力可能でフォーカスされていない状態                     using (Graphics graphics = this.CreateGraphics())                     {                         // 描画をいったん消去(背景色で塗りつぶす)                         Brush brush = new SolidBrush(this.BackColor);                         graphics.FillRectangle(brush, this.ClientRectangle);                         // プレースホルダーの色を取得                         Color placeholderColor = CreateNeutralColor();                         if (!this._placeholderColor.IsEmpty)                         {                             placeholderColor = this._placeholderColor;                         }                         // プレースホルダーのテキストを描画する                         graphics.DrawString(_placeholderText, this.Font, new SolidBrush(placeholderColor), 1, 1);                     }                 }             }         }         // 前景色と背景色の中間色を作成         private Color CreateNeutralColor()         {             Color color = Color.FromArgb(                 (this.ForeColor.A >> 1 + this.BackColor.A >> 1),                 (this.ForeColor.R >> 1 + this.BackColor.R >> 1),                 (this.ForeColor.G >> 1 + this.BackColor.G >> 1),                 (this.ForeColor.B >> 1 + this.BackColor.B >> 1));             return color;         }     } }  | 
					
上記の例では、System.WindowsForms名前空間にあるTextBoxクラスを継承して、PlaceholderTextBoxクラスを作成しています。
継承したサブクラスのPlaceholderTextBoxコントロールにプレースホルダーのテキストを表示する処理を追加します。
プレースホルダーのテキストを表示する処理は、TextBoxクラスのWndProcメソッドをoverride(オーバーライド)して処理を実装します。
テキストボックスが描画(ペイント)される時に、プレースホルダーの描画処理を行います。
テキストボックスにフォーカスがなく、テキストも入力されていない場合は、PlaceholderTextプロパティに設定されているテキストをプレースホルダーのテキストとして、DoawStringメソッドで描画します。
プレースホルダーのテキストを描画する際は、いったnテキストボックスの背景色で塗りつぶしてから文字列を描画がします。
ここで作成するコントロールには、プレースホルダーのテキストを表示する文字の色を設定できるようにPlaceholderColorプロパティも追加しています。
PlaceholderColorプロパティは値が設定されていない(Color.Emptyの)場合は、テキストボックスの背景色(BackColor)と前景色(ForeColor)の間の色をデフォルト(既定値)で設定するようにしています。
サンプルプログラム (.NET Framework)
作成したプレースホルダーを表示するプロパティを持つPlaceholderTextBoxコントロールをフォームに配置します。
ユーザーインターフェース
フォームには、プレースホルダーのテキストを表示するテキストボックス(textBox1)、プレースホルダ―のテキストを入力するテキストボックス(textBox2)、右揃えに設定するテキストボックス(button1)を配置します。

ソースコード
ボタンをクリックした時に、指定されたテキストをプレースホルダーのテキストに設定する処理を記述します。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34  | 
						using System; using System.Windows.Forms; namespace WindowsFormsApp1 {     public partial class Form1 : Form     {         // コンストラクタ         public Form1()         {             InitializeComponent();             // ボタンのクリックイベント             this.button1.Click += Button1_Click;         }         // ボタンクリック時のイベントメソッド         private void Button1_Click(object sender, EventArgs e)         {             try             {                 // プレースホルダ―のテキストを取得                 string placeHolderText = this.textBox1.Text;                 // プレースホルダ―のテキストを設定                 this.placeholderTextBox1.PlaceholderText = placeHolderText;             }             catch (Exception ex)             {                 MessageBox.Show(ex.Message);             }         }     } }  | 
					
プログラムの実行
プロジェクトをビルドして実行(デバッグ)してフォームを表示します。

テキストボックスに文字列を入力して揃え位置を確認します。

ボタンをクリックしてプレースホルダーのテキストを設定します。

テキストボックスにプレースホルダーのテキストが描画(表示)されます。
テキストボックスにフォーカスを移動してみます。

フォーカスされている状態では、プレースホルダーのテキストは描画されません。
テキストボックスに文字を入力して、フォーカスを外します。

テキストが設定されている状態では、プレースホルダーのテキストは描画されません。