覆盖一些.Net Framework控件的绘图以更改其边框颜色?
情景
我正在使用第三方Windows视觉主题。
当我看到我的应用程序时,它看起来像这样:
但是,当我使用普通的Aero主题时,它看起来到处都是可怕的白色边框:
题
我知道应用程序中使用的颜色方案取决于视觉风格,但是:
我可以inheritanceTextBox
, ComboBox
和TabControl
来改变绘制的边框颜色以使用更暗的颜色吗? 如何?
UPDATE
我的TextBoxes使用的是Fixed3D
属性值Fixed3D
我的ComboBoxes使用FlatStyle
属性,其值为Flat
,并设置为DropDownList
您可以捕获WM_PAINT
或WM_ERASEBKGND
消息并手动绘制边框:
[DllImport("user32.dll")] static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport("user32.dll")] static extern int ReleaseDC(IntPtr hwnd, IntPtr hDC); protected override void WndProc(ref Message m) { IntPtr hdc; if (m.Msg == 0x14) //WM_ERASEBKGND { hdc = GetWindowDC(m.HWnd); if (hdc != IntPtr.Zero) { using (Graphics g = Graphics.FromHdc(hdc)) { g.DrawRectangle(Pens.Red, 0, 0, this.Width-1, this.Height-1); } ReleaseDC(m.HWnd, hdc); } base.WndProc(ref m); }
然而,当文本框失去焦点时,它确实存在问题。
具有边框的ComboBox的VB.Net解决方案(不完整,需要使用3dBorder进行改进)
#Region " Option Statements " Option Explicit On Option Strict On Option Infer Off #End Region #Region " Imports " Imports System.ComponentModel #End Region ''' ''' A custom user control. ''' Public Class ElektroComboBox : Inherits ComboBox #Region " Properties " ''' ''' Gets or sets the border color. ''' ''' The border color. Public Property BorderColor() As Color Get Return borderColor1 End Get Set(ByVal value As Color) Me.borderColor1 = value Me.Invalidate() End Set End Property ''' ''' The border color. ''' Private borderColor1 As Color = SystemColors.ControlDark ''' ''' Gets or sets the border style. ''' ''' The border color. Public Property BorderStyle As ButtonBorderStyle Get Return borderStyle1 End Get Set(ByVal value As ButtonBorderStyle) Me.borderStyle1 = value Me.Invalidate() End Set End Property ''' ''' The border style. ''' Private borderStyle1 As ButtonBorderStyle = ButtonBorderStyle.Solid #End Region #Region " Enumerations " ''' ''' Specifies a Windows Message. ''' Private Enum WindowsMessages WM_PAINT = &HF End Enum #End Region #Region " Windows Procedure " ''' ''' Processes Windows messages. ''' ''' The Windows to process. Protected Overrides Sub WndProc(ByRef m As Message) MyBase.WndProc(m) Select Case m.Msg Case WindowsMessages.WM_PAINT Me.DrawBorder() End Select End Sub #End Region #Region " Private Methods " ''' ''' Draws a border on the control surface. ''' Private Sub DrawBorder() Using g As Graphics = Graphics.FromHwnd(Me.Handle) ControlPaint.DrawBorder(Graphics.FromHwnd(Me.Handle), Me.ClientRectangle, Me.borderColor1, Me.borderStyle1) End Using End Sub #End Region End Class
具有边框的GroupBox的VB.Net解决方案(不完整,它在设计模式下以错误的方式重绘所包含的控件)
#Region " Option Statements " Option Explicit On Option Strict On Option Infer Off #End Region #Region " Imports " Imports System.ComponentModel #End Region #Region " ElektroGroupBox " ''' ''' A custom user control. ''' Public Class ElektroGroupBox : Inherits GroupBox #Region " Properties " ''' ''' Gets or sets the border color. ''' ''' The border color. Public Property BorderColor As Color Get Return Me.borderColor1 End Get Set(ByVal value As Color) Me.borderColor1 = value Me.Invalidate() End Set End Property ''' ''' The border color. ''' Private borderColor1 As Color = SystemColors.ControlDark ''' ''' Gets or sets the border style. ''' ''' The border color. Public Property BorderStyle As ButtonBorderStyle Get Return borderStyle1 End Get Set(ByVal value As ButtonBorderStyle) Me.borderStyle1 = value Me.Invalidate() End Set End Property ''' ''' The border style. ''' Private borderStyle1 As ButtonBorderStyle = ButtonBorderStyle.Solid #End Region #Region " Events " ''' ''' Handles the event. ''' ''' A that contains the event data. Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs) ' MyBase.OnPaint(e) Me.DrawBorder(e) End Sub #End Region #Region " Private Methods " ''' ''' Draws a border on the control surface. ''' Private Sub DrawBorder(ByVal e As PaintEventArgs) ' The groupbox header text size. Dim textSize As Size = TextRenderer.MeasureText(Me.Text, Me.Font) ' The width of the blankspace drawn at the right side of the text. Dim blankWidthSpace As Integer = 3 ' The thex horizontal offset. Dim textOffset As Integer = 7 ' The rectangle where to draw the border. Dim borderRect As Rectangle = e.ClipRectangle With borderRect .Y = .Y + (textSize.Height \ 2) .Height = .Height - (textSize.Height \ 2) End With ' The rectangle where to draw the header text. Dim textRect As Rectangle = e.ClipRectangle With textRect .X = .X + textOffset .Width = (textSize.Width - blankWidthSpace) .Height = textSize.Height End With ' Draw the border. ControlPaint.DrawBorder(e.Graphics, borderRect, Me.borderColor1, Me.borderStyle1) ' Fill the text rectangle. e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), textRect) ' Draw the text on the text rectangle. textRect.Width = textSize.Width + (blankWidthSpace * 2) ' Fix the right side space. e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), textRect) End Sub #End Region End Class #End Region