WinForm程序中的类TextBox的自定义控件, 添加失去焦点的功能

原理:

一、在控件的后台代码中, 添加布尔类型的属性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;
                    }
                }
            }
        }

时间: 2024-10-07 05:27:09

WinForm程序中的类TextBox的自定义控件, 添加失去焦点的功能的相关文章

在C# WinForm程序中创建控件数组及相应的事件处理

控件数组是VB提供的一个优秀的设计解决方案,它能很方便快捷的处理大批同类控件的响应和时间处理,但不知为什么在C#中这个优秀特性没有传承下来,甚为可惜,本文将要探讨就是如何在C# WinForm程序实现它.首先请看界面 在上面的界面中,本人想实现一个42个元素的Button数组来实现一个日历的功能,上面显示出了一部分. 其中采用了网格布局来放置这些按钮.手工创建为全部按钮后,在窗体类中代码中定义成员变量控件数组: private Button[] btns;然后在构造函数中初始化: btns =

记一次WinForm程序中主进程打开子进程并传递参数的操作过程(进程间传递参数)

目标:想在WinForm程序之间传递参数.以便子进程作出相应的处理. 一种错误的方法 父进程的主程序: 1 ProcessStartInfo psi = new ProcessStartInfo(); 2 psi.FileName = "ProcessChild.exe"; 3 psi.Arguments = txtArgs.Text; 4 Process.Start(psi);//主要问题在这里 子进程的主程序: 1 txtArgs.Text = Process.GetCurrent

Halcon的HWindowControl控件在WinForm程序中的使用介绍(重点解决图片缩放的问题)

 Halcon的HWindowControl控件在WinForm程序中的使用介绍(重点解决图片缩放的问题) 2016-12-04 20:11 362人阅读 评论(4) 收藏 举报  分类: Halcon 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] HWindowControl控件初步使用 最近在学习新的视觉处理工具–Halcon软件包,本人学习的主要是HDevelop.Halcon与C#混编以及Halcon与C++混编.这里再多缀一句:11版本后C++编程,包含的是h

在Winform程序中设置管理员权限及为用户组添加写入权限

在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行程序具有管理员权限或者设置运行程序的目录具有写入的权限,如果是在操作系统里面,我们可以设置运行程序以管理员身份运行,或者设置Users用户组在运行目录中具有写入权限都可以解决问题,不过如果我们想通过C#代码进行自动的处理,那么应该如何实现呢? 1.系统设置管理员权限或者目录写入权限 如果我们需要让程序以管理员身份运行,那么可以通过设置快捷方式的属性或者应用程序的属性为[以管理员身份运行此程序]即可实现,如

(转)在Winform程序中设置管理员权限及为用户组添加写入权限

本文转载自:http://www.cnblogs.com/wuhuacong/p/5645172.html 在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行程序具有管理员权限或者设置运行程序的目录具有写入的权限,如果是在操作系统里面,我们可以设置运行程序以管理员身份运行,或者设置Users用户组在运行目录中具有写入权限都可以解决问题,不过如果我们想通过C#代码进行自动的处理,那么应该如何实现呢? 1.系统设置管理员权限或者目录写入权限 如果我们需要让程

【VC++学习笔记四】MFC应用程序中框架类的获取

一.文档类中 获取视图: 先获取主窗体,在根据主窗体获取视图 pMain->GetActiveDocument();注意类型转换 由于文档中可能包含多个视图,可以按照下面函数获取: CView*   CTestDoc::GetView(CRuntimeClass*   pClass) { CView*  pView; POSITION   pos=GetFirstViewPosition(); while(pos!=NULL) { pView=GetNextView(pos); if(!pVie

winform程序中界面的跳转问题

首先是我们进行窗口间的跳转,尤其注意的是winform程序里面的空间都是中线程安全的.但是注意的是如果你在一个线程中操纵另外的控件,这时候会提示你一个错误,这个错误的解决方法准备单独的在另一篇文章中来讲. 好了,这时候回到主题上吧,怎么来实现界面间的跳转吧!假设我们想要从Form1跳转到Form2,那么可以有以下的集中方法: 1. 使用form的show属性(注:show弹出来的是普通无模式窗体,与下个要讲的ShowDialog是有区别的) Form2 frm=new Form2(); frm.

VS建立的Winform程序中连接Oracle数据库能正常运行在Web中却不能正常连接运行可能原因(本文来自博客园深蓝居)

我们平时使用的都是32位的机器进行开发,装的都是32位的软件,但是我们的服务器一般都是64位的,所以有时也需要在64位的环境下装一个VS调试程序.最近遇到的一个问题就是一个同事换了一个电脑,用的是X64的Windows 2008作为操作系统,要进行Oracle的数据库连接,所以也装了64位的Oracle客户端.如果是控制应用项目或者WinForm项目可以正常连接Oracle,但是Web项目在程序中打开Oracle连接时,系统抛出了异常: 尝试加载 Oracle 客户端库时引发 BadImageF

C# WinForm程序中使用Unity3D控件 (转)

https://www.cnblogs.com/cnxkey/articles/5394378.html 最近在自学Unity3D,打算使用这个时髦.流行.强大的游戏引擎开发一个三维业务展示系统,不过发现游戏的UI和业务系统的UI还是有一定的差别,很多的用户还是比较习惯WinForm或者WPF中的UI形式,于是在网上搜了一下WinForm和Unity3D如何集成,结果不是非常令人满意,绝大多数的回答是“No Way”,也有人给出了使用WebBrowser控件的形式,说实话这种还算是比较靠谱的,以