简体   繁体   中英

Change the font color of a winform datetimepicker when disabled

I am creating custom controls that use the standard font color when disabled in a windows form application but am stumped at getting the DateTimePicker to work.

I've found a number of answers but they're 10+ years old and no longer seem to work. This is a simple answer from 2007, however when I replicate that it works to set the Font on enabled/disabled but the outlying combobox graphic is no longer painted.

Doing some more digging I've found some more complete code to draw the combobox graphics, which combined with the first simple answer I've created the following 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();
    }
}

But in my case the ComboBoxRenderer is not supported so it won't paint, and I don't see another easy way to draw it without building a control from scratch.

So am I going about this the right way? Is there a simple answer like in the first link provided, or with the code provided is there an alternative to using ComboBoxRenderer ?

I have done something similar, but I didn't think it was necessary to paint the drop-down button when the control was disabled, as it can't be clicked anyway. When the control is disabled set the style to UserPaint , otherwise let the control paint itself.

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));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM