How to avoid color changes when button is disabled?
Asked Answered
B

7

21

We have a Windows Forms project with quite a few FlatStyle buttons.

When we disable the buttons, the colors of the buttons are changed automatically Frown | :(

Is it possible to override this somehow, so we can control the colors ourselves?

Banc answered 10/9, 2013 at 10:58 Comment(4)
Do you want the text color to appear as activated or the background color?Blayze
Text color as activated and backcolor as activated - actually, for some of the buttons, everything as when activated...Banc
Seeing a user banging away at a button that was disabled but doesn't look disabled is a UI tragedy. You'll get no help from Winforms to invoke such a tragedy, it implements the UI design guide rules. The rules that every user is familiar with. You'll need to create your own tragedy with your own button control.Sophia
Totally agree - the issue is being taken care of by button image changes.Banc
B
29

You need to use the EnabledChanged event to set the desired color. Here is an example.

private void Button1_EnabledChanged(object sender, System.EventArgs e)
{
    Button1.ForeColor = sender.enabled == false ? Color.Blue : Color.Red;
    Button1.BackColor = Color.AliceBlue;
}

Use the desired colors according to your requirement.

Also you need to use the paint event.

private void Button1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
    dynamic btn = (Button)sender;
    dynamic drawBrush = new SolidBrush(btn.ForeColor);
    dynamic sf = new StringFormat {
        Alignment = StringAlignment.Center,
        LineAlignment = StringAlignment.Center
    };
    Button1.Text = string.Empty;
    e.Graphics.DrawString("Button1", btn.Font, drawBrush, e.ClipRectangle, sf);
    drawBrush.Dispose();
    sf.Dispose();
}
Blayze answered 10/9, 2013 at 11:12 Comment(3)
Excellent. Only problem is that the image on the buttons still change colors... I have tried using e.Graphics.DrawImage(), but it didn't help. The image still change colors :( But your solution fixes the text color issue.Banc
Glad to know it helped. Please mark as answered if you got the answer to your question.Blayze
For a label or checkbox, make sure you set the AutoSize property to false.Den
H
5

To get less-fuzzy text, use the TextRenderer class instead:

private void Button1_Paint(object sender, PaintEventArgs e)
{
     Button btn = (Button)sender;
     // Make sure Text is not also written on button.
     btn.Text = string.Empty;
     // Set flags to center text on the button.
     TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak;   // center the text
     // Render the text onto the button.
     TextRenderer.DrawText(e.Graphics, "Hello", btn.Font, e.ClipRectangle, btn.ForeColor, flags);
}

And use the Button1_EnabledChanged method as in the Harsh's answer.

Helminthology answered 1/5, 2014 at 21:22 Comment(1)
I would avoid setting properties in a paint event.Sniffle
D
2

I use ClientRectangle instead of e.ClipRectangle to avoid clip effect when the button is partialy repaint :

e.Graphics.Clear(BackColor);
using (var drawBrush = new SolidBrush(ForeColor))
using (var sf = new StringFormat
{
    Alignment = StringAlignment.Center,
    LineAlignment = StringAlignment.Center
})
{
    e.Graphics.DrawString(Text, Font, drawBrush, ClientRectangle, sf);
}
Druse answered 31/5, 2018 at 7:19 Comment(0)
B
2

On the EnableChanged event of the button

private void button1_EnabledChanged(object sender, EventArgs e)
    {
        if (button1.Enabled == false)
        {
            button1.ForeColor = Color.DarkGray; //or pick the color you want when not enabled
        }
        else
        {
            button1.ForeColor = Color.White; //same here with the color
        }
    }
Buxton answered 10/2, 2021 at 1:25 Comment(0)
I
1

I followed the following approach :- The Click() event of the button can be controlled using custom variable.

private bool btnDisabled;

private void btnClick(object sender, EventArgs e)
{
   if (!btnDisabled) return;
}

This way the button doesn't even need to be disabled. The button still has the click feel but no action will be taken. Have to use the right colors to communicate that the button is disabled.

Ichor answered 5/12, 2017 at 16:0 Comment(0)
D
-1

Never too late for a suggestion:

public class BlackButton : Button
{
    #region #Private Members
    private bool m_BasePaint = false;
    #endregion #Private Members

    #region #Ctor
    public BlackButton() : base()
    {
        base.ForeColor = Color.White;
        base.BackColor = Color.Black;
        this.DisabledForeColor = Color.FromArgb(0x6D, 0x6D, 0x6D);
    }
    #endregion #Ctor

    #region #Public Interface
    public Color DisabledForeColor
    {
        get;
        set;
    }
    #endregion #Public Interface

    #region #Overrides
    public override string Text
    {
        get
        {
            if (m_BasePaint)
                return "";
            return base.Text;
        }
        set
        {
            base.Text = value;
        }
    }
    protected override void OnPaint(PaintEventArgs pevent)
    {
        m_BasePaint = true;
        base.OnPaint(pevent);
        m_BasePaint = false;

        TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak; 

        TextRenderer.DrawText(pevent.Graphics, 
            Text, 
            base.Font, 
            ClientRectangle, 
            base.Enabled ? base.ForeColor : this.DisabledForeColor, 
            flags);
    }
    #endregion #Overrides
}
Despondency answered 12/7, 2019 at 20:46 Comment(0)
A
-1

Another way to do this is to use the Pre_Render event. The example use Telerik but standard buttons should work fine too.

protected void radButton_PreRender(object sender, EventArgs e)
{
    RadButton btn = sender as RadButton;
    btn.BackColor = btn.Checked ? Color.LightBlue : Color.White;
}
Astatic answered 14/4, 2022 at 21:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.