言語フィルタ:
概要
テキストボックスに透かし文字(ヒントと言う場合もあります)を表示する方法を紹介します。
テキストボックスに透かし文字を表示すると次のようになります。
| 未入力の時 |
入力済みの時 |
 |
 |
対象コントロール
- System.Windows.Forms.RichTextBox
- System.Windows.Forms.TextBox
解説
透かし文字とは、テキストボックスが空の場合に表示される文字のことです。テキストボックスにフォーカスが設定されるか、文字が入力されると透かし文字は非表示になります。
テキストボックスからフォーカスが失われた時に OnLeave メソッドが呼び出されます。このメソッドでテキストが空の場合は、透かし文字を Text プロパティに設定することで透かし文字を表示することが出来ます。
テキストボックスにフォーカスが設定された時に OnEnter メソッドが呼び出されます。このメソッドで透かし文字が表示されている場合は Text プロパティを空に設定することで透かし文字を非表示にすることが出来ます。
テキストボックスに透かし文字が表示されているか、通常のテキストが表示されているかを判定するために Text プロパティをオーバーライドします。そして、透かし文字を表示しているかを表すフラグを一つ用意します。Text プロパティに空文字が設定された場合にはフラグを True に設定します。それ以外の文字が設定された場合にはフラグを False に設定します。このフラグを参照することで、テキストボックスに透かし文字が表示されているかを判断することが出来るようになります。
テキストボックスに文字列を入力した場合に Text プロパティの Set アクセサは呼び出されません。そのため完全にフラグで透かし文字が表示されているかどうかを制御することは出来ません。そこで透かし文字を表示する時にテキストボックスが空かどうかを判定するには、基本クラスの Text プロパティを参照するようにします。
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
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 メソッドを呼ばないようにします。
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
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 プロパティをオーバーライドしています。
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
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;
}
}
}
}
}