Skip Navigation Linksホーム > ライブラリ > テキストボックス > テキストボックスに透かし文字を表示する

テキストボックスに透かし文字を表示する

言語フィルタ:

概要

テキストボックスに透かし文字(ヒントと言う場合もあります)を表示する方法を紹介します。

テキストボックスに透かし文字を表示すると次のようになります。

未入力の時 入力済みの時
sample1 sample2

対象コントロール

  • System.Windows.Forms.RichTextBox
  • System.Windows.Forms.TextBox

解説

透かし文字とは、テキストボックスが空の場合に表示される文字のことです。テキストボックスにフォーカスが設定されるか、文字が入力されると透かし文字は非表示になります。

テキストボックスからフォーカスが失われた時に OnLeave メソッドが呼び出されます。このメソッドでテキストが空の場合は、透かし文字を Text プロパティに設定することで透かし文字を表示することが出来ます。

テキストボックスにフォーカスが設定された時に OnEnter メソッドが呼び出されます。このメソッドで透かし文字が表示されている場合は Text プロパティを空に設定することで透かし文字を非表示にすることが出来ます。

テキストボックスに透かし文字が表示されているか、通常のテキストが表示されているかを判定するために Text プロパティをオーバーライドします。そして、透かし文字を表示しているかを表すフラグを一つ用意します。Text プロパティに空文字が設定された場合にはフラグを True に設定します。それ以外の文字が設定された場合にはフラグを False に設定します。このフラグを参照することで、テキストボックスに透かし文字が表示されているかを判断することが出来るようになります。

テキストボックスに文字列を入力した場合に Text プロパティの Set アクセサは呼び出されません。そのため完全にフラグで透かし文字が表示されているかどうかを制御することは出来ません。そこで透かし文字を表示する時にテキストボックスが空かどうかを判定するには、基本クラスの Text プロパティを参照するようにします。

展開されたイメージ 透かし文字の設定 - Visual Basic
コピーイメージ コードのコピー
Private empty As Boolean

Protected Overrides Sub OnEnter(ByVal e As System.EventArgs)
    If Me.empty = True Then
        ' 透かし文字を非表示にする
        Me.empty = False
        MyBase.Text = String.Empty
    End If

    MyBase.OnEnter(e)
End Sub

Protected Overrides Sub OnLeave(ByVal e As System.EventArgs)
    MyBase.OnLeave(e)

    If MyBase.Text = String.Empty Then
        ' テキストボックスが空の場合は透かし文字を表示する
        Me.empty = True
        MyBase.Text = "透かし文字"
    Else
        Me.empty = False
    End If
End Sub

Public Overrides Property Text() As String
    Get
        Return MyBase.Text
    End Get
    Set(ByVal value As String)
        If value = String.Empty Then
            ' テキストボックスが空の場合は透かし文字を表示する
            Me.empty = True
            MyBase.Text = "透かし文字"
        Else
            Me.empty = False
            MyBase.Text = value
        End If
    End Set
End Property
展開されたイメージ 透かし文字の設定 - C#
コピーイメージ コードのコピー
private bool empty;

protected override void OnEnter(EventArgs e)
{
    if (this.empty == true)
    {
        // 透かし文字を非表示にする
        this.empty = false;
        base.Text = string.Empty;
    }

    base.OnEnter(e);
}

protected override void OnLeave(EventArgs e)
{
    base.OnLeave(e);

    if (base.Text == string.Empty)
    {
        // テキストボックスが空の場合は透かし文字を表示する
        this.empty = true;
        base.Text = "透かし文字";
    }
    else
    {
        this.empty = false;
    }
}

public override string Text
{
    get { return base.Text; }
    set
    {
        if (value == string.Empty)
        {
            // テキストボックスが空の場合は透かし文字を表示する
            this.empty = true;
            base.Text = "透かし文字";
        }
        else
        {
            this.empty = false;
            base.Text = value;
        }
    }
}

透かし文字を表示または非表示にする時に Text プロパティに値を設定すると、Modified プロパティが必ず False になります。それを防ぐために Text プロパティに値を設定する前に Modified プロパティの値を保持しておき、Text プロパティに値を設定後に Modified プロパティに保持しておいた値を戻してやります。

また、その際に不要に ModifiedChanged イベントが発生するのを防ぐために OnModifiedChanged メソッドをオーバーライドします。透かし文字の設定で OnModifiedChanged メソッドが呼ばれた場合は基本クラスの OnModifiedChanged メソッドを呼ばないようにします。

展開されたイメージ Modified の制御 - Visual Basic
コピーイメージ コードのコピー
Private modifiedChanging As Boolean

    ' 透かし文字を表示または非表示にするタイミング
    Dim m As Boolean = Me.Modified
    MyBase.Text = "透かし文字"
    Me.modifiedChanging = True
    Me.Modified = m
    Me.modifiedChanging = False

Protected Overrides Sub OnModifiedChanged(ByVal e As System.EventArgs)
    If Me.modifiedChanging = True Then
        Return
    End If

    MyBase.OnModifiedChanged(e)
End Sub
展開されたイメージ Modified の制御 - C#
コピーイメージ コードのコピー
private bool modifiedChanging;

    // 透かし文字を表示または非表示にするタイミング
    bool m = this.Modified;
    base.Text = text;
    this.modifiedChanging = true;
    this.Modified = m;
    this.modifiedChanging = false;

protected override void OnModifiedChanged(EventArgs e)
{
    if (this.modifiedChanging == true)
    {
        return;
    }

    base.OnModifiedChanged(e);
}

ソースコード

TextBox コントロールに透かし文字を表示するサンプルを紹介します。

透かし文字を表示中かどうかを示す empty フラグを追加しています。

透かし文字を表示または非表示にする時に ModifiedChanged イベントが発生しないように OnModifiedChanged メソッドをオーバーライドしています。

透かし文字を示す WatermarkText プロパティと、その文字色を示す WatermarkColor プロパティを追加しています。

ForeColor プロパティは通常のテキストを表示中はそれの、透かし文字を表示中はそれの前景色を取得または設定するようになっています。透かし文字を表示中に通常の前景色を取得または設定できるように ForegroundColor プロパティを追加しています。

透かし文字を表示中はパスワード文字が表示されないように PasswordChar プロパティをオーバーライドしています。

展開されたイメージ Visual Basic
コピーイメージ コードのコピー
Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms

Namespace Extentions

    Public Class WatermarkTextBox
        Inherits System.Windows.Forms.TextBox

        Private empty As Boolean
        Private modifiedChanging As Boolean

        Public Sub New()
            Me.empty = True
            Me._WatermarkText = String.Empty
            Me._WatermarkColor = Color.DarkGray
            Me._ForegroundColor = Me.ForeColor
        End Sub

        Private Sub SetBaseText(ByVal text As String)
            Dim m As Boolean = Me.Modified
            MyBase.Text = text
            Me.modifiedChanging = True
            Me.Modified = m
            Me.modifiedChanging = False
        End Sub

        Protected Overrides Sub OnModifiedChanged(ByVal e As System.EventArgs)
            If Me.modifiedChanging = True Then
                Return
            End If

            MyBase.OnModifiedChanged(e)
        End Sub

        Protected Overrides Sub OnEnter(ByVal e As System.EventArgs)
            If Me.empty = True Then
                Me.empty = False
                MyBase.PasswordChar = Me._PasswordChar
                MyBase.ForeColor = Me.ForegroundColor
                Me.SetBaseText(String.Empty)
            End If

            MyBase.OnEnter(e)
        End Sub

        Protected Overrides Sub OnLeave(ByVal e As System.EventArgs)
            MyBase.OnLeave(e)

            If MyBase.Text = String.Empty AndAlso Me.WatermarkText <> String.Empty Then
                Me.empty = True
                MyBase.PasswordChar = Nothing
                MyBase.ForeColor = Me.WatermarkColor
                Me.SetBaseText(Me.WatermarkText)
            Else
                Me.empty = False
            End If
        End Sub

        <RefreshProperties(RefreshProperties.Repaint)> _
        Public Overrides Property Text() As String
            Get
                If Me.empty = True Then
                    Return String.Empty
                End If

                Return MyBase.Text
            End Get
            Set(ByVal value As String)
                If value = String.Empty AndAlso Me.WatermarkText <> String.Empty Then
                    Me.empty = True
                    MyBase.PasswordChar = Nothing
                    MyBase.ForeColor = Me.WatermarkColor
                    MyBase.Text = Me.WatermarkText
                Else
                    Me.empty = False
                    MyBase.PasswordChar = Me._PasswordChar
                    If MyBase.ForeColor <> Me._ForegroundColor Then
                        MyBase.ForeColor = Me._ForegroundColor
                    End If
                    MyBase.Text = value
                End If
            End Set
        End Property

        Public Overrides Property ForeColor() As Color
            Get
                Return MyBase.ForeColor
            End Get
            Set(ByVal value As Color)
                If Me.empty = True Then
                    Me._WatermarkColor = value
                Else
                    Me._ForegroundColor = value
                End If

                MyBase.ForeColor = value
            End Set
        End Property

        Private _ForegroundColor As Color
        <Category("表示")> _
        <DefaultValue(GetType(Color), "WindowText")> _
        <Description("ForeColor プロパティに設定したコントロールの前景色を取得または設定します。")> _
        Public Property ForegroundColor() As Color
            Get
                Return Me._ForegroundColor
            End Get
            Set(ByVal value As Color)
                Me._ForegroundColor = value

                If Me.empty = False AndAlso MyBase.ForeColor <> Me._ForegroundColor Then
                    MyBase.ForeColor = value
                End If
            End Set
        End Property

        Private _PasswordChar As Char
        Public Shadows Property PasswordChar() As Char
            Get
                If Me.empty = True Then
                    Return Nothing
                End If

                Return MyBase.PasswordChar
            End Get
            Set(ByVal value As Char)
                Me._PasswordChar = value

                If Me.empty = False Then
                    MyBase.PasswordChar = value
                End If
            End Set
        End Property

        Private _WatermarkText As String
        <Category("表示")> _
        <DefaultValue("")> _
        <Description("テキストが空の場合に表示する文字列を設定または取得します。")> _
        <RefreshProperties(RefreshProperties.Repaint)> _
        Public Property WatermarkText() As String
            Get
                Return Me._WatermarkText
            End Get
            Set(ByVal value As String)
                Me._WatermarkText = value

                If Me.Text = String.Empty AndAlso value <> String.Empty Then
                    Me.empty = True
                    MyBase.PasswordChar = Nothing
                    MyBase.ForeColor = Me.WatermarkColor
                    Me.SetBaseText(value)
                ElseIf Me.Text = String.Empty AndAlso value = String.Empty Then
                    Me.Text = String.Empty
                End If
            End Set
        End Property

        Private _WatermarkColor As Color
        <Category("表示")> _
        <DefaultValue(GetType(Color), "DarkGray")> _
        <Description("テキストが空の場合に表示する文字列の色を設定または取得します。")> _
        Public Property WatermarkColor() As Color
            Get
                Return Me._WatermarkColor
            End Get
            Set(ByVal value As Color)
                Me._WatermarkColor = value

                If Me.empty = True Then
                    MyBase.ForeColor = value
                End If
            End Set
        End Property

    End Class

End Namespace
展開されたイメージ C#
コピーイメージ コードのコピー
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace Extentions
{
    public class WatermarkTextBox : System.Windows.Forms.TextBox
    {
        private bool empty;
        private bool modifiedChanging;

        public WatermarkTextBox()
        {
            this.empty = true;
            this._WatermarkText = string.Empty;
            this._WatermarkColor = Color.DarkGray;
            this._ForegroundColor = this.ForeColor;
        }

        private void SetBaseText(string text)
        {
            bool m = this.Modified;
            base.Text = text;
            this.modifiedChanging = true;
            this.Modified = m;
            this.modifiedChanging = false;
        }

        protected override void OnModifiedChanged(EventArgs e)
        {
            if (this.modifiedChanging == true)
            {
                return;
            }

            base.OnModifiedChanged(e);
        }

        protected override void OnEnter(EventArgs e)
        {
            if (this.empty == true)
            {
                this.empty = false;
                base.PasswordChar = this._PasswordChar;
                base.ForeColor = this.ForegroundColor;
                this.SetBaseText(string.Empty);
            }

            base.OnEnter(e);
        }

        protected override void OnLeave(EventArgs e)
        {
            base.OnLeave(e);

            if (base.Text == string.Empty && this.WatermarkText != string.Empty)
            {
                this.empty = true;
                base.PasswordChar = '\0';
                base.ForeColor = this.WatermarkColor;
                this.SetBaseText(this.WatermarkText);
            }
            else
            {
                this.empty = false;
            }
        }

        [RefreshProperties(RefreshProperties.Repaint)]
        public override string Text
        {
            get
            {
                if (this.empty == true)
                {
                    return string.Empty;
                }

                return base.Text;
            }
            set
            {
                if (value == string.Empty && this.WatermarkText != string.Empty)
                {
                    this.empty = true;
                    base.PasswordChar = '\0';
                    base.ForeColor = this.WatermarkColor;
                    base.Text = this.WatermarkText;
                }
                else
                {
                    this.empty = false;
                    base.PasswordChar = this._PasswordChar;
                    if (base.ForeColor != this._ForegroundColor)
                    {
                        base.ForeColor = this._ForegroundColor;
                    }
                    base.Text = value;
                }
            }
        }

        public override Color ForeColor
        {
            get { return base.ForeColor; }
            set
            {
                if (this.empty == true)
                {
                    this._WatermarkColor = value;
                }
                else
                {
                    this._ForegroundColor = value;
                }

                base.ForeColor = value;
            }
        }

        private Color _ForegroundColor;
        [Category("表示")]
        [DefaultValue(typeof(Color), "WindowText")]
        [Description("ForeColor プロパティに設定したコントロールの前景色を取得または設定します。")]
        public Color ForegroundColor
        {
            get { return this._ForegroundColor; }
            set
            {
                this._ForegroundColor = value;

                if (this.empty == false && base.ForeColor != this._ForegroundColor)
                {
                    base.ForeColor = value;
                }
            }
        }

        private Char _PasswordChar;
        public new Char PasswordChar
        {
            get
            {
                if (this.empty == true)
                {
                    return '\0';
                }

                return base.PasswordChar;
            }
            set
            {
                this._PasswordChar = value;

                if (this.empty == false)
                {
                    base.PasswordChar = value;
                }
            }
        }

        private string _WatermarkText;
        [Category("表示")]
        [DefaultValue("")]
        [Description("テキストが空の場合に表示する文字列を設定または取得します。")]
        [RefreshProperties(RefreshProperties.Repaint)]
        public string WatermarkText
        {
            get { return this._WatermarkText; }
            set
            {
                this._WatermarkText = value;

                if (this.Text == string.Empty && value != string.Empty)
                {
                    this.empty = true;
                    base.PasswordChar = '\0';
                    base.ForeColor = this.WatermarkColor;
                    this.SetBaseText(value);
                }
                else if (this.Text == string.Empty && value == string.Empty)
                {
                    this.Text = string.Empty;
                }
            }
        }

        private Color _WatermarkColor;
        [Category("表示")]
        [DefaultValue(typeof(Color), "DarkGray")]
        [Description("テキストが空の場合に表示する文字列の色を設定または取得します。")]
        public Color WatermarkColor
        {
            get { return this._WatermarkColor; }
            set
            {
                this._WatermarkColor = value;

                if (this.empty == true)
                {
                    base.ForeColor = value;
                }
            }
        }
    }
}