如何使用ControlPaint.DrawBorder方法修改ComboBox的边框颜色?
How can I use the ControlPaint.DrawBorder method to modifiy the border color of a ComboBox?
我有一个需求,需要设置Combobox控件的边框颜色。
我在 Google 中搜索了实现 ControlPaint.Drawborder
.
的示例代码
我发现的并不理想。边框颜色未修改。
在下面的代码中,您将看到两个关键函数,WndProc
和 PaintControlBorder()
,它们用于接收底层 windows 事件并处理它们。
后者用于绘制控件的边框。用Visual Studio调试后,发现执行了PaintControlBorder()
函数中的代码。
为什么边框颜色没有变化?
[ToolboxItem(true)]
public class ModifiedComboBox : ComboBox
{
new public System.Windows.Forms.DrawMode DrawMode { get; set; }
public Color HighlightColor { get; set; } //set select item highlight color
private IntPtr hDC;
private Graphics gdc;
private const int WM_ERASEBKGND = 0x14; // some windows message id
private const int WM_PAINT = 0xF;
private const int WM_NC_PAINT = 0x85;
private const int WM_PRINTCLIENT = 0x318;
private const int WM_MOUSEHOVER = 0x2A1;
private const int WM_MOUSELEAVE = 0x2A3;
[DllImport("user32")]
private static extern IntPtr GetDC(IntPtr hWnd);
private Rectangle rectale;
public ModifiedComboBox()
{
hDC = GetDC(Handle);
gdc = Graphics.FromHdc(hDC);
SetStyle(ControlStyles.Selectable, false);
base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.HighlightColor = Color.Gray;
this.DrawItem += new DrawItemEventHandler(AdvancedComboBox_DrawItem); //t bind draw item handler
rectale = new Rectangle(0, 0, Width, Height);
}
public void AdvancedComboBox_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0)
return;
ComboBox combo = sender as ComboBox;
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
e.Graphics.FillRectangle(new SolidBrush(HighlightColor), e.Bounds);
//e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.BackColor), new Point(e.Bounds.X, e.Bounds.Y));
e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.ForeColor), new Point(e.Bounds.X, e.Bounds.Y));
}
else
{
e.Graphics.FillRectangle(new SolidBrush(combo.BackColor), e.Bounds);
e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.ForeColor), new Point(e.Bounds.X, e.Bounds.Y));
}
e.DrawFocusRectangle();
}
protected override void WndProc(ref Message m)// windows message handler
{
if (this.DropDownStyle == ComboBoxStyle.Simple)
{
base.WndProc(ref m);
return;
}
switch (m.Msg)
{
case WM_NC_PAINT:
break;
case WM_PAINT:
base.WndProc(ref m);
PaintControlBorder();
break;
default:
base.WndProc(ref m);
break;
}
}
private void PaintControlBorder()
{
ControlPaint.DrawBorder(gdc, this.ClientRectangle, Color.Orange, ButtonBorderStyle.Solid);
}
}
在 Windows 窗体中,您永远不会存储控件的图形对象。
您可以使用其中一种图形方法(Paint、DrawItem 等)提供的方法,或者像本例一样,在需要时创建一个新方法,然后立即处理它。
在此示例中,隐式地将 Graphics 对象创建包含在 using
块中。
这是一个简单的例子,使用ControlPaint.DrawBorder, that show how draw a border around a ComboBox control, using a Graphics object derived from the control Handle (Graphics.FromHwnd(this.Handle)
) on a WM_PAINT
message received overriding the control's WndProc。
示例自定义控件公开了一个 public 属性、BorderColor
,它允许更改边框的颜色。
using System.ComponentModel;
using System.Drawing;
using System.Security.Permissions;
using System.Windows.Forms;
[DesignerCategory("Code")]
class ComboSimpleBorder : ComboBox
{
private const int WM_PAINT = 0xF;
private Color m_BorderColor = Color.Red;
public ComboSimpleBorder() { }
[Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[EditorBrowsable(EditorBrowsableState.Always), Category("Appearance")]
[Description("Get or Set the Color of the Control's border")]
public Color BorderColor
{
get => this.m_BorderColor;
set { this.m_BorderColor = value; this.Invalidate(); }
}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == WM_PAINT) {
using (Graphics g = Graphics.FromHwnd(this.Handle)) {
ControlPaint.DrawBorder(g, this.ClientRectangle, this.m_BorderColor, ButtonBorderStyle.Solid);
}
m.Result = IntPtr.Zero;
}
}
}
我有一个需求,需要设置Combobox控件的边框颜色。
我在 Google 中搜索了实现 ControlPaint.Drawborder
.
的示例代码
我发现的并不理想。边框颜色未修改。
在下面的代码中,您将看到两个关键函数,WndProc
和 PaintControlBorder()
,它们用于接收底层 windows 事件并处理它们。
后者用于绘制控件的边框。用Visual Studio调试后,发现执行了PaintControlBorder()
函数中的代码。
为什么边框颜色没有变化?
[ToolboxItem(true)]
public class ModifiedComboBox : ComboBox
{
new public System.Windows.Forms.DrawMode DrawMode { get; set; }
public Color HighlightColor { get; set; } //set select item highlight color
private IntPtr hDC;
private Graphics gdc;
private const int WM_ERASEBKGND = 0x14; // some windows message id
private const int WM_PAINT = 0xF;
private const int WM_NC_PAINT = 0x85;
private const int WM_PRINTCLIENT = 0x318;
private const int WM_MOUSEHOVER = 0x2A1;
private const int WM_MOUSELEAVE = 0x2A3;
[DllImport("user32")]
private static extern IntPtr GetDC(IntPtr hWnd);
private Rectangle rectale;
public ModifiedComboBox()
{
hDC = GetDC(Handle);
gdc = Graphics.FromHdc(hDC);
SetStyle(ControlStyles.Selectable, false);
base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.HighlightColor = Color.Gray;
this.DrawItem += new DrawItemEventHandler(AdvancedComboBox_DrawItem); //t bind draw item handler
rectale = new Rectangle(0, 0, Width, Height);
}
public void AdvancedComboBox_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0)
return;
ComboBox combo = sender as ComboBox;
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
e.Graphics.FillRectangle(new SolidBrush(HighlightColor), e.Bounds);
//e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.BackColor), new Point(e.Bounds.X, e.Bounds.Y));
e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.ForeColor), new Point(e.Bounds.X, e.Bounds.Y));
}
else
{
e.Graphics.FillRectangle(new SolidBrush(combo.BackColor), e.Bounds);
e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.ForeColor), new Point(e.Bounds.X, e.Bounds.Y));
}
e.DrawFocusRectangle();
}
protected override void WndProc(ref Message m)// windows message handler
{
if (this.DropDownStyle == ComboBoxStyle.Simple)
{
base.WndProc(ref m);
return;
}
switch (m.Msg)
{
case WM_NC_PAINT:
break;
case WM_PAINT:
base.WndProc(ref m);
PaintControlBorder();
break;
default:
base.WndProc(ref m);
break;
}
}
private void PaintControlBorder()
{
ControlPaint.DrawBorder(gdc, this.ClientRectangle, Color.Orange, ButtonBorderStyle.Solid);
}
}
在 Windows 窗体中,您永远不会存储控件的图形对象。
您可以使用其中一种图形方法(Paint、DrawItem 等)提供的方法,或者像本例一样,在需要时创建一个新方法,然后立即处理它。
在此示例中,隐式地将 Graphics 对象创建包含在 using
块中。
这是一个简单的例子,使用ControlPaint.DrawBorder, that show how draw a border around a ComboBox control, using a Graphics object derived from the control Handle (Graphics.FromHwnd(this.Handle)
) on a WM_PAINT
message received overriding the control's WndProc。
示例自定义控件公开了一个 public 属性、BorderColor
,它允许更改边框的颜色。
using System.ComponentModel;
using System.Drawing;
using System.Security.Permissions;
using System.Windows.Forms;
[DesignerCategory("Code")]
class ComboSimpleBorder : ComboBox
{
private const int WM_PAINT = 0xF;
private Color m_BorderColor = Color.Red;
public ComboSimpleBorder() { }
[Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[EditorBrowsable(EditorBrowsableState.Always), Category("Appearance")]
[Description("Get or Set the Color of the Control's border")]
public Color BorderColor
{
get => this.m_BorderColor;
set { this.m_BorderColor = value; this.Invalidate(); }
}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == WM_PAINT) {
using (Graphics g = Graphics.FromHwnd(this.Handle)) {
ControlPaint.DrawBorder(g, this.ClientRectangle, this.m_BorderColor, ButtonBorderStyle.Solid);
}
m.Result = IntPtr.Zero;
}
}
}