禁用时更改 winform datetimepicker 的字体颜色
Change the font color of a winform datetimepicker when disabled
我正在创建在 windows 表单应用程序中禁用时使用标准字体颜色的自定义控件,但在让 DateTimePicker
工作时遇到困难。
我找到了很多答案,但它们已经有 10 多年的历史了,似乎不再有效。 This 是 2007 年的一个简单答案,但是当我复制它时,它可以在 enabled/disabled
上设置 Font
但不再绘制外围组合框图形。
进行更多挖掘后,我发现了一些更完整的代码来绘制组合框图形,结合第一个简单的答案,我创建了以下 class:
public partial class CustomDatetimePicker : DateTimePicker
{
public CustomDatetimePicker()
{
InitializeComponent();
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs pe)
{
//Graphics g = this.CreateGraphics();
Graphics g = pe.Graphics;
//The dropDownRectangle defines position and size of dropdownbutton block,
//the width is fixed to 17 and height to 16. The dropdownbutton is aligned to right
Rectangle dropDownRectangle = new Rectangle(ClientRectangle.Width - 17, 0, 17, 16);
Brush bkgBrush;
Brush txtBrush;
ComboBoxState visualState;
//When the control is enabled the brush is set to Backcolor,
//otherwise to color stored in _backDisabledColor
if (this.Enabled)
{
bkgBrush = new SolidBrush(SystemColors.Window);
txtBrush = new SolidBrush(SystemColors.WindowText);
visualState = ComboBoxState.Normal;
}
else
{
bkgBrush = new SolidBrush(SystemColors.InactiveBorder);
txtBrush = new SolidBrush(SystemColors.WindowText);
visualState = ComboBoxState.Disabled;
}
// Painting...in action
//Filling the background
g.FillRectangle(bkgBrush, 0, 0, ClientRectangle.Width, ClientRectangle.Height);
//Drawing the datetime text
g.DrawString(this.Text, this.Font, txtBrush, 0, 2);
//Drawing the dropdownbutton using ComboBoxRenderer
if (ComboBoxRenderer.IsSupported)
{
ComboBoxRenderer.DrawDropDownButton(g, dropDownRectangle, visualState);
}
g.Dispose();
bkgBrush.Dispose();
}
}
但在我的例子中 ComboBoxRenderer
不受支持,因此它不会绘制,而且我没有看到另一种不从头开始构建控件的简单绘制方法。
那么我这样做是否正确?是否有像第一个 link 提供的简单答案,或者提供的代码是否有使用 ComboBoxRenderer
的替代方法?
我也做过类似的事情,但是我觉得没有必要在控件被禁用的时候画下拉按钮,因为无论如何都不能点击。当控件被禁用时,将样式设置为 UserPaint
,否则让控件自行绘制。
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var graphics = e.Graphics;
var clientRectangle = ClientRectangle;
var font = Font;
var text = Text;
var textSize = TextRenderer.MeasureText(text, font);
var textBounds = DrawingHelper.AlignInRectangle(clientRectangle, textSize, ContentAlignment.MiddleLeft);
graphics.FillRectangle(new SolidBrush(SystemColors.Control), ClientRectangle);
ControlPaint.DrawBorder(graphics, clientRectangle, SystemColors.ControlDark, ButtonBorderStyle.Solid);
TextRenderer.DrawText(graphics, text, font, textBounds, SystemColors.WindowText);
}
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
SetStyle();
}
public void SetStyle()
{
if (DesignMode)
return;
SetStyle(ControlStyles.UserPaint, !Enabled);
Invalidate();
}
public static class DrawingHelper
{
public static Rectangle AlignInRectangle(Rectangle outer, Size inner, ContentAlignment alignment)
{
int x = 0;
int y = 0;
switch (alignment)
{
case ContentAlignment.BottomLeft:
case ContentAlignment.MiddleLeft:
case ContentAlignment.TopLeft:
x = outer.X;
break;
case ContentAlignment.BottomCenter:
case ContentAlignment.MiddleCenter:
case ContentAlignment.TopCenter:
x = Math.Max(outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
break;
case ContentAlignment.BottomRight:
case ContentAlignment.MiddleRight:
case ContentAlignment.TopRight:
x = outer.Right - inner.Width;
break;
}
switch (alignment)
{
case ContentAlignment.TopCenter:
case ContentAlignment.TopLeft:
case ContentAlignment.TopRight:
y = outer.Y;
break;
case ContentAlignment.MiddleCenter:
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleRight:
y = outer.Y + (outer.Height - inner.Height) / 2;
break;
case ContentAlignment.BottomCenter:
case ContentAlignment.BottomRight:
case ContentAlignment.BottomLeft:
y = outer.Bottom - inner.Height;
break;
}
return new Rectangle(x, y, Math.Min(inner.Width, outer.Width), Math.Min(inner.Height, outer.Height));
}
}
我正在创建在 windows 表单应用程序中禁用时使用标准字体颜色的自定义控件,但在让 DateTimePicker
工作时遇到困难。
我找到了很多答案,但它们已经有 10 多年的历史了,似乎不再有效。 This 是 2007 年的一个简单答案,但是当我复制它时,它可以在 enabled/disabled
上设置 Font
但不再绘制外围组合框图形。
进行更多挖掘后,我发现了一些更完整的代码来绘制组合框图形,结合第一个简单的答案,我创建了以下 class:
public partial class CustomDatetimePicker : DateTimePicker
{
public CustomDatetimePicker()
{
InitializeComponent();
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs pe)
{
//Graphics g = this.CreateGraphics();
Graphics g = pe.Graphics;
//The dropDownRectangle defines position and size of dropdownbutton block,
//the width is fixed to 17 and height to 16. The dropdownbutton is aligned to right
Rectangle dropDownRectangle = new Rectangle(ClientRectangle.Width - 17, 0, 17, 16);
Brush bkgBrush;
Brush txtBrush;
ComboBoxState visualState;
//When the control is enabled the brush is set to Backcolor,
//otherwise to color stored in _backDisabledColor
if (this.Enabled)
{
bkgBrush = new SolidBrush(SystemColors.Window);
txtBrush = new SolidBrush(SystemColors.WindowText);
visualState = ComboBoxState.Normal;
}
else
{
bkgBrush = new SolidBrush(SystemColors.InactiveBorder);
txtBrush = new SolidBrush(SystemColors.WindowText);
visualState = ComboBoxState.Disabled;
}
// Painting...in action
//Filling the background
g.FillRectangle(bkgBrush, 0, 0, ClientRectangle.Width, ClientRectangle.Height);
//Drawing the datetime text
g.DrawString(this.Text, this.Font, txtBrush, 0, 2);
//Drawing the dropdownbutton using ComboBoxRenderer
if (ComboBoxRenderer.IsSupported)
{
ComboBoxRenderer.DrawDropDownButton(g, dropDownRectangle, visualState);
}
g.Dispose();
bkgBrush.Dispose();
}
}
但在我的例子中 ComboBoxRenderer
不受支持,因此它不会绘制,而且我没有看到另一种不从头开始构建控件的简单绘制方法。
那么我这样做是否正确?是否有像第一个 link 提供的简单答案,或者提供的代码是否有使用 ComboBoxRenderer
的替代方法?
我也做过类似的事情,但是我觉得没有必要在控件被禁用的时候画下拉按钮,因为无论如何都不能点击。当控件被禁用时,将样式设置为 UserPaint
,否则让控件自行绘制。
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var graphics = e.Graphics;
var clientRectangle = ClientRectangle;
var font = Font;
var text = Text;
var textSize = TextRenderer.MeasureText(text, font);
var textBounds = DrawingHelper.AlignInRectangle(clientRectangle, textSize, ContentAlignment.MiddleLeft);
graphics.FillRectangle(new SolidBrush(SystemColors.Control), ClientRectangle);
ControlPaint.DrawBorder(graphics, clientRectangle, SystemColors.ControlDark, ButtonBorderStyle.Solid);
TextRenderer.DrawText(graphics, text, font, textBounds, SystemColors.WindowText);
}
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
SetStyle();
}
public void SetStyle()
{
if (DesignMode)
return;
SetStyle(ControlStyles.UserPaint, !Enabled);
Invalidate();
}
public static class DrawingHelper
{
public static Rectangle AlignInRectangle(Rectangle outer, Size inner, ContentAlignment alignment)
{
int x = 0;
int y = 0;
switch (alignment)
{
case ContentAlignment.BottomLeft:
case ContentAlignment.MiddleLeft:
case ContentAlignment.TopLeft:
x = outer.X;
break;
case ContentAlignment.BottomCenter:
case ContentAlignment.MiddleCenter:
case ContentAlignment.TopCenter:
x = Math.Max(outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
break;
case ContentAlignment.BottomRight:
case ContentAlignment.MiddleRight:
case ContentAlignment.TopRight:
x = outer.Right - inner.Width;
break;
}
switch (alignment)
{
case ContentAlignment.TopCenter:
case ContentAlignment.TopLeft:
case ContentAlignment.TopRight:
y = outer.Y;
break;
case ContentAlignment.MiddleCenter:
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleRight:
y = outer.Y + (outer.Height - inner.Height) / 2;
break;
case ContentAlignment.BottomCenter:
case ContentAlignment.BottomRight:
case ContentAlignment.BottomLeft:
y = outer.Bottom - inner.Height;
break;
}
return new Rectangle(x, y, Math.Min(inner.Width, outer.Width), Math.Min(inner.Height, outer.Height));
}
}