带有工作背景色的 DateTimePicker






4.84/5 (25投票s)
一个可以显示我们想要的背景颜色的 DateTimePicker 派生类。
引言
一些 .NET 中的 Windows Forms 控件不允许我们更改 BackColor
。 DateTimePicker
就是如此。 另一个已知的问题是,当控件被禁用时,文本的可读性很差。 在此示例中,我派生了这样一个类,引入了设置 BackColor
的能力,并且我添加了一个新的属性 BackDisabledColor
。
背景
BackColor
属性在基类 Control
中定义,因此在派生类中可用。 此外,此类属性通常在设计时在“属性”窗口中可用。 但是,标准的 DateTimePicker
无法绘制用户选择的背景颜色。 如果我们设置它,什么也不会发生。 因此,在 DateTimePicker
类中,此属性被属性 [Browsable(false)]
覆盖。 这样,我们就不必看到无用的属性。
DateTimePicker
控件使用一些 Windows 功能来绘制控件。 因此,WM_PAINT
消息不由类本身的 OnPaint
方法管理。 OnPaint
方法永远不会被调用。 为了强制在我们的派生类中调用该方法,我们必须在构造函数中将控件样式设置为 UserPaint
this.SetStyle(ControlStyles.UserPaint, true);
现在,我们可以使用我们的 OnPaint
,但是我们无法利用基类 OnPaint
,因为它什么也不做。 为了检查这一点,请尝试以下代码
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
base.OnPaint(e);
}
您将看到控件什么也不显示。 因此,现在我们承担了绘制控件的全部责任。 为了保持有用和清晰的代码,我们放弃了两个原始功能,否则需要大量的编码。 第一个是可选的复选框,用于允许最终用户跳过显示的日期 (ShowCheckBox
属性)。 第二种是能够直接使用键盘输入日期部分,而不是通过日历。
Using the Code
要使用该代码,只需将 *DateTimePicker.cs* 文件添加到您的项目中,然后像使用其基类一样使用 BCDateTimePicker
。
主要工作由 OnPaint
方法的重写完成。 在这里,我们放入代码来绘制背景矩形,填充我们想要的颜色,然后绘制下拉按钮和表示日期的文本。 绘制下拉按钮的工作由 ComboBoxRenderer.DrawDropDownButton
完成。
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
Graphics g = this.CreateGraphics();
//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;
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(this.BackColor);
visualState = ComboBoxState.Normal;
}
else {
bkgBrush = new SolidBrush(this._backDisabledColor);
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, Brushes.Black, 0, 2);
//Drawing the dropdownbutton using ComboBoxRenderer
ComboBoxRenderer.DrawDropDownButton(g, dropDownRectangle, visualState);
g.Dispose();
bkgBrush.Dispose();
}
为了再次在“属性”窗口中显示 BackColor
属性,我们重写它,将 Browsable
属性设置为 true
。
[Browsable(true)]
public override Color BackColor
{
get { return base.BackColor; }
set { base.BackColor = value; }
}
此外,我们创建一个 BackDisabledColor
属性,允许开发人员在设计时选择颜色。
[Category("Appearance"),
Description("The background color of the component when disabled")]
[Browsable(true)]
public Color BackDisabledColor
{
get { return _backDisabledColor; }
set { _backDisabledColor = value; }
}
关注点
在重写的 OnPaint
方法中,我从控件创建了一个新的 Graphics
对象,而不是使用 PaintEventArgs
返回的对象。 事实上,当使用 ShowUpDown
模式时,基类仅使受用户交互影响的日期部分区域无效。 当使用长格式时,这会产生不正确的文本显示。 由于我没有找到其他方法来扩展事件参数传递的 Graphics
对象的剪辑区域,因此采用的解决方案是创建一个新的 Graphics
,允许在控件的整个范围内进行绘制。