65.9K
CodeProject 正在变化。 阅读更多。
Home

带有工作背景色的 DateTimePicker

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (25投票s)

2008年11月3日

CPOL

3分钟阅读

viewsIcon

219447

downloadIcon

8767

一个可以显示我们想要的背景颜色的 DateTimePicker 派生类。

引言

一些 .NET 中的 Windows Forms 控件不允许我们更改 BackColorDateTimePicker 就是如此。 另一个已知的问题是,当控件被禁用时,文本的可读性很差。 在此示例中,我派生了这样一个类,引入了设置 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 属性,允许开发人员在设计时选择颜色。

BCDateTimePickerProperties.gif

[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,允许在控件的整个范围内进行绘制。

© . All rights reserved.