使用PictureBox和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(); } }