透かし文字(WaterMark)表示機能つきComboBox
(2016.02.01追記)TextBox版は以下の記事を参照ください。
透かし文字表示機能つきTextBox(WinForms) - hnx8 開発室
HNXgrepでも使用している「未入力のときに入力を促す内容の透かし文字」を表示するComboBoxのソースを紹介してみます。
未入力の場合は、太線囲みのようにグレーなど特定の色で表示されるよう、ComboBoxのクラスを拡張し、以下2つのプロパティを追加しています。
- WatermarkText:未入力時に表示するテキスト内容
- WatermarkColor:未入力時テキストの表示色
他は、通常のComboBoxと使い方はまったく一緒です。
using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; /// <summary> /// 改良版ComboBox /// <para>・ウォーターマーク機能追加</para> /// </summary> class WatermarkComboBox : ComboBox { // ウォーターマーク表示関連変数 private bool _watermark; //ウォーターマーク表示中はtrue private string _watermarkText; //ウォーターマーク表示内容text private Color _watermarkColor; //ウォーターマーク表示時の前景色 private Color _foreColor; //通常表示時の前景色 private bool _isDropDownList; //ドロップダウンリストでウォーターマーク表示中か /// <summary> /// コンストラクタ /// </summary> public WatermarkComboBox() { _watermark = false; _watermarkText = ""; _watermarkColor = SystemColors.GrayText; _foreColor = SystemColors.WindowText; _isDropDownList = false; } /// <summary> /// テキストが空の場合に表示する文字列を取得・設定します。 /// </summary> [Category("表示")] [DefaultValue("")] [Description("テキストが空の場合に表示する文字列です。")] [RefreshProperties(RefreshProperties.Repaint)] public string WatermarkText { get { return this._watermarkText; } set { this._watermarkText = value; trySetWatermark(); //ウォーターマーク表示を試みる } } /// <summary> /// テキストが空の場合に表示する文字列の色を取得・設定します。 /// </summary> [Category("表示")] [DefaultValue(typeof(Color), "GrayText")] [Description("テキストが空の場合に表示する文字列の色です。")] public Color WatermarkColor { get { return this._watermarkColor; } set { this._watermarkColor = value; trySetWatermark(); //ウォーターマーク表示を試みる } } public override Color ForeColor { get { //描画時にForeColorプロパティどおりの色で描画しているみたいなので、ForeColorどおりの色を返す //ただしデザインモードでは通常色どおりに返す return (DesignMode) ? this._foreColor : base.ForeColor; } set { this._foreColor = value; if (_watermark == false) { //ウォーターマーク表示中でなければ、ただちに色適用 base.ForeColor = value; } } } [RefreshProperties(RefreshProperties.Repaint)] public override string Text { get { return (_watermark) ? string.Empty : base.Text; } set { if (string.IsNullOrEmpty(value)) { //空文字列が指定された trySetWatermark(); //ウォーターマーク表示を試みる } else if (_watermark) { //適切な文字列が設定された。ウォーターマーク表示設定解除 resetWatermark(value); } else { //テキスト上書き base.Text = value; } } } /// <summary> /// ウォーターマーク表示設定を試みる /// </summary> /// <returns></returns> private bool trySetWatermark() { if (string.IsNullOrEmpty(_watermarkText) == false && string.IsNullOrEmpty(base.Text) && base.SelectedIndex < 0 && base.Focused == false) { //DropDownListは、ウォーターマーク表示のためDropDownにスタイル変更 _isDropDownList = (base.DropDownStyle == ComboBoxStyle.DropDownList && DesignMode == false); if (_isDropDownList) { base.DropDownStyle = ComboBoxStyle.DropDown; } //ウォーターマーク設定 base.ForeColor = WatermarkColor; base.Text = _watermarkText; _watermark = true; return true; } return false; } /// <summary> /// ウォーターマーク表示設定を解除する /// </summary> /// <param name="value"></param> private void resetWatermark(string value) { if (_isDropDownList) { base.DropDownStyle = ComboBoxStyle.DropDownList; _isDropDownList = false; } if (value != null) { base.Text = value; } base.ForeColor = _foreColor; _watermark = false; } //イベント処理対応 protected override void OnEnter(EventArgs e) { if (_watermark) { //ウォーターマーク表示解除 resetWatermark(""); } base.OnEnter(e); } protected override void OnLeave(EventArgs e) { base.OnLeave(e); trySetWatermark(); } protected override void OnSelectedIndexChanged(EventArgs e) { if (SelectedIndex >= 0) { //ウォーターマーク表示解除 resetWatermark(null); } base.OnSelectedIndexChanged(e); } //本来は、TextChanged,ForeColorChangedイベントもオーバーライドして抑止するのが望ましい }
※参考にしたページ
コンボボックスに透かし文字を表示する(※WindowsVista以降のみ)
http://youryella.wankuma.com/Library/Extensions/ComboBox/Watermark.aspx
テキストボックスに透かし文字を表示する (実装)
http://youryella.wankuma.com/Library/Extensions/TextBox/Watermark.aspx
「WindowsXP対応」のウォーターマーク機能つきComboBoxがほしかったので、上記ページを参考にして作ってみました。
もっともXPのサポート期限はあと2年弱なので、いまさら需要なんかないとは思いますが・・・・。