原理:
一、在控件的后台代码中, 添加布尔类型的属性CanFocus
二、在控件的构造函数中, 注册Enter事件的处理方法. 并在处理方法中,根据CanFocus属性的值来决定是否可以丢失焦点, 如果可以则调用Windows消息的发送类.
三、在处理方法中,调用User32.dll类库, 发送window消息.
示例代码:
//Windows消息的发送方法
//WMMessageHepler.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; namespace YXT.Common { public class WMMessageHepler { private const int WM_KILLFOCUS = 0x0008; //发送失去焦点的Window消息 public static void SendBlurMsg(IntPtr hWnd) { PostMessage(hWnd, WM_KILLFOCUS, 0, 0); } [DllImport("user32.dll")] private static extern void PostMessage(IntPtr hWnd, int msg, int wParam, int lParam); [DllImport("User32.dll", EntryPoint = "SendMessage")] private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam); } }
//自定义控件的关键代码
//WatermarkTextBox.cs
using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using YXT.Common; namespace YXT.Client.Controls { [ToolboxBitmap(typeof(TextBox))] public class WatermarkTextBox : TextBox { public WatermarkTextBox() { this.BorderStyle = BorderStyle.FixedSingle; this.Enter += new EventHandler(WatermarkTextBox_Enter); } void WatermarkTextBox_Enter(object sender, EventArgs e) { if (this.SetBlur) { this.OnBlur(); } } private Color _borderColor = Color.Red; private string _watermarkTitle; private Color _watermarkColor = Color.DarkGray; private bool _setBlur = false; /// <summary> /// 控件是否失去焦点 /// </summary> public bool SetBlur { get { return this._setBlur; } set { this._setBlur = value; Invalidate(); } } /// <summary> /// 水印字体提示 /// </summary> public string WatermarkTitle { get { return _watermarkTitle; } set { _watermarkTitle = value; Invalidate(); } } /// <summary> /// 边框颜色 /// </summary> public Color BorderColor { get { return _borderColor; } set { _borderColor = value; Invalidate(); } } /// <summary> /// 水印颜色 /// </summary> public Color WatermarkColor { get { return _watermarkColor; } set { _watermarkColor = value; Invalidate(); } } private void OnBlur() { WMMessageHepler.SendBlurMsg(this.Handle); } protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == 0xf || m.Msg == 0x14 || m.Msg == 0x85) { if (this.BorderStyle == BorderStyle.FixedSingle) { using (Graphics g = Graphics.FromHwnd(this.Handle)) { using (var pen = new Pen(_borderColor)) { g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1); WmPaint(ref m); } } } } } private void WmPaint(ref Message m) { using (Graphics graphics = Graphics.FromHwnd(base.Handle)) { if (Text.Length == 0 && !string.IsNullOrEmpty(_watermarkTitle) && !Focused) { TextFormatFlags format = TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter; if (RightToLeft == RightToLeft.Yes) { format |= TextFormatFlags.RightToLeft | TextFormatFlags.Right; } TextRenderer.DrawText( graphics, _watermarkTitle, Font, base.ClientRectangle, _watermarkColor, format); } } } } }
//使用示例
//方法使用示例
ControlsEdintor(string controlsName) { //控件编辑时 修改样式 foreach (var value in this.Controls) { var textBox = value as WatermarkTextBox; if (controlsName == "编辑") { if (textBox != null) { textBox.BorderStyle = BorderStyle.FixedSingle; textBox.ReadOnly = false; textBox.SetBlur = false; } } else { if (textBox != null) { textBox.BorderStyle = BorderStyle.None; textBox.ReadOnly = true; textBox.SetBlur = true; } } } }