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();
        }
    }

不足之處:

文本沒能居中,可以把字體大小往上調讓字體充滿控件的高度。調整控件的大小之后,需要手動調整字體的大小
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM