C# 用WinForm实现在文本框无内容时显示浅色提示文本

本文介绍如何在C#的WinForm应用中,通过继承TextBox并利用GDI+绘制,实现在文本框内容为空时显示提示文本。文章讨论了避免频繁绘图的方法,即使用Timer进行延时GDI+绘制,并详细解释了OnHandleCreated、OnTextChanged和OnGotFocus三个关键事件的重写逻辑。虽然目前采用延时方法,但作者认为存在优化空间,期待后续改进。

代码想要实现的功能是:

实现原理:

一、继承TextBox类,重写TextBox的三个事件(OnHandleCreated,OnTextChanged,OnGotFocus)

二、 不能直接在TextBoxChange中增加判断,容易频繁GDI绘图

三、 使用Timer进行延时GDI+,避免频繁绘图

代码实现:

先添加一个用户控件

将新建的UserControl继承TextBox

public partial class UserControl1 : TextBox

生成一个方法,实现当文本改变或焦点改变时判断文本长度,当Text.Length=0时,用GDI在TextBox上绘制显示需要的文本

int i = 0;        private void ReDraw(TextBox textBox)
        {
            Graphics g;
            g = Graphics.FromHwnd(textBox.Handle);
            if (textBox.Text.Length <= 0)
            {
                Font font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);//设置字体,大小,粗细
                Brush sbrush = new SolidBrush(Color.Gray);//设置颜色
                g.DrawString("请输入文本......", font, sbrush, 1, 1);
                g.Save();
                i = 0;
            }
            else
            {
                if (i == 0)
                {
                    g.Clear(textBox.BackColor);
                    Font font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);//设置字体,大小,粗细
                    Brush sbrush = new SolidBrush(this.ForeColor);//设置颜色
                    g.DrawString(Text, font, sbrush, 0, 0);
                    g.Save();
                    i++;
                }
            }
        }

之后我发现在触发OnTextChanged时直接在文本上面绘图,会导致界面无法更新到我需要显示的页面。

原因可能为触发OnTextChanged时,系统默认的GDI的绘图速度慢于我写的这个方法。

所以增加一个Timer,在文字发生改变时实现GDI延时绘图

public UserControl1()
        {
            InitializeComponent();
            timer = new Timer();
            timer.Interval = 30;
            timer.Tick += Timer_Tick;
            timer.Enabled = false;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            ReDraw(this);
            timer.Enabled = false;
        }

最后将OnHandleCreated,OnTextChanged,OnGotFocus三个事件重写

OnHandleCreated实现文本框加载时,默认显示提示文本。

OnTextChanged实现文字改变时,判断是否显示提示文本。

OnGotFocus当TextBox窗体失去焦点后重新获得焦点时,显示提示文本。

protected override void OnHandleCreated(EventArgs e)
        {
            ReDraw(this);
            base.OnHandleCreated(e);
        }
        protected override void OnTextChanged(EventArgs e)
        {
            ReDraw(this);
            base.OnTextChanged(e);
        }
        protected override void OnGotFocus(EventArgs e)
        {
            ReDraw(this);
            base.OnGotFocus(e);
        }

该代码还有优化的空间,应该可以用其他的办法替代延时的方法。想到再补充。。

所有代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TextBoxControler
{
    public partial class UserControl1 : TextBox
    {
        private Timer timer;
        public UserControl1()
        {
            InitializeComponent();
            timer = new Timer();
            timer.Interval = 30;
            timer.Tick += Timer_Tick;
            timer.Enabled = false;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            ReDraw(this);
            timer.Enabled = false;
        }

        protected override void OnHandleCreated(EventArgs e)
        {
            ReDraw(this);
            base.OnHandleCreated(e);
        }
        protected override void OnTextChanged(EventArgs e)
        {
            ReDraw(this);
            base.OnTextChanged(e);
        }
        protected override void OnGotFocus(EventArgs e)
        {
            ReDraw(this);
            base.OnGotFocus(e);
        }
        int i = 0;
        private void ReDraw(TextBox textBox)
        {
            Graphics g;
            g = Graphics.FromHwnd(textBox.Handle);
            if (textBox.Text.Length <= 0)
            {
                Font font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);//设置字体,大小,粗细
                Brush sbrush = new SolidBrush(Color.Gray);//设置颜色
                g.DrawString("请输入文本......", font, sbrush, 1, 1);
                g.Save();
                i = 0;
            }
            else
            {
                if (i == 0)
                {
                    g.Clear(textBox.BackColor);
                    Font font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);//设置字体,大小,粗细
                    Brush sbrush = new SolidBrush(this.ForeColor);//设置颜色
                    g.DrawString(Text, font, sbrush, 0, 0);
                    g.Save();
                    i++;
                }
            }
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值