• C# Winfrom 自定义控件——带图片的TextBox


    效果:

    描述:

    本来是想用GDI在左边画图片上去的,文本是居中对齐,如果文本是左对齐,文本会把图片遮住控件长这样:
    但这样做,输入框在获取焦点时候,会把图片挡住就像这样:
    输入完成之后图片就会显示完整。所以我又采用了PictureBox+TextBox组合的方式来完成这种效果。完成这种效果需要完成以下步骤:
    0.分别设置PictureBox和TextBox的控件的Anchor和Dock属性,这样在窗体上拉动控件大小的时候,图片框和文本输入框能一起变大;
    1.调整TextBox的border为none;
    2.调整PictureBox的backColor为White;
    3.调整作为控件载体的UserControl的BackColor为White;
    4.设置作为控件载体的UserControl的BorderStyle为FixedSingle;因为这里需要重绘UserContorl的边框就需要这样的设置,我这里重绘成了DarkRed颜色。

    提醒:

    如果你想写一些文本框的事件就要像定义MyTextChanged那样暴露出来。还有就是,这里如果override UserControlde的OnPaint方法我是没能完成控件边框的重绘。
     (我也不清楚什么时候重写WndProc什么时候重写OnPaint。)

    代码:

     public partial class MyPicturerTextBox : UserControl
        {
            public MyPicturerTextBox()
            {
                InitializeComponent();
                this.BorderStyle = BorderStyle.FixedSingle;
            }
    
    
            private Image userImg;
            [Description("文本框里的图片")]
            public Image UserImg
            {
                get { return userImg; }
    
                set
                {
    
                    if (value != null)
                    {
                        this.Img.Image = value;
                    }
                    userImg = value;
    
                }
            }
    
            private string txt;
            [Description("输入的文本")]
            public string Txt
            {
                get { return txt; }
    
                set
                {
                    if (!string.IsNullOrEmpty(value))
                    {
                        this.textBox.Text = value;
                    }
                    txt = value;
                }
            }
            [Description("TextChanged事件")]
            public event EventHandler MyTextChanged;
    
            private void textBox_TextChanged(object sender, EventArgs e)
            {
                MyTextChanged?.Invoke(sender, e);
            }
           
            /// <summary> 
            /// 获得当前进程,以便重绘控件 
            /// </summary> 
            /// <param name="hWnd"></param> 
            /// <returns></returns> 
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            static extern IntPtr GetWindowDC(IntPtr hWnd);
            [System.Runtime.InteropServices.DllImport("user32.dll")]
            static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
    
    
            protected override void WndProc(ref Message m)
            {
    
                base.WndProc(ref m);
                if (m.Msg == 0xf || m.Msg == 0x133)
                {
                    //拦截系统消息,获得当前控件进程以便重绘。 
                    //一些控件(如TextBox、Button等)是由系统进程绘制,重载OnPaint方法将不起作用. 
                    //所有这里并没有使用重载OnPaint方法绘制TextBox边框。 
                    // 
                    //MSDN:重写 OnPaint 将禁止修改所有控件的外观。 
                    //那些由 Windows 完成其所有绘图的控件(例如 Textbox)从不调用它们的 OnPaint 方法, 
                    //因此将永远不会使用自定义代码。请参见您要修改的特定控件的文档, 
                    //查看 OnPaint 方法是否可用。如果某个控件未将 OnPaint 作为成员方法列出, 
                    //则您无法通过重写此方法改变其外观。 
                    // 
                    //MSDN:要了解可用的 Message.Msg、Message.LParam 和 Message.WParam 值, 
                    //请参考位于 MSDN Library 中的 Platform SDK 文档参考。可在 Platform SDK(“Core SDK”一节) 
                    //下载中包含的 windows.h 头文件中找到实际常数值,该文件也可在 MSDN 上找到。 
                    IntPtr hDC = GetWindowDC(m.HWnd);
                    if (hDC.ToInt32() == 0)
                    {
                        return;
                    }
    
                    //只有在边框样式为FixedSingle时自定义边框样式才有效 
                    if (this.BorderStyle == BorderStyle.FixedSingle)
                    {
                        //边框Width为1个像素 
                        System.Drawing.Pen pen = new Pen(Brushes.DarkRed, 1);
    
                        //绘制边框 
                        System.Drawing.Graphics g = Graphics.FromHdc(hDC);
                        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                        g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1);
                        pen.Dispose();
                    }
                    //返回结果 
                    m.Result = IntPtr.Zero;
                    //释放 
                    ReleaseDC(m.HWnd, hDC);
                }
            }
    
            protected override void OnResize(EventArgs e)
            {
                base.OnResize(e);
                this.Refresh();
            }
        }

    不足之处:

    文本没能居中,可以把字体大小往上调让字体充满控件的高度。调整控件的大小之后,需要手动调整字体的大小
     
  • 相关阅读:
    解决phpmailer可以在windows下面发送成功, 在linux下面失败的问题
    centos安装svn
    linux下面配置安装nodejs+npm
    排序与搜索
    链表
    栈和队列
    顺序表
    初识算法、数据结构
    Linux_02
    Linux_01
  • 原文地址:https://www.cnblogs.com/HelloQLQ/p/11298308.html
Copyright © 2020-2023  润新知