Mohammad
Mohammad

Reputation: 109

How can I change the font color in a groupbox when I disable the groupbox

I am using a Groupbox in c# and at first, it is Enabled.

when I use Groupbox1.Enabled = false, it's fore color (and everythings' forecolor which is in it) change to default black. and even the command label1.Forecolor = Color.White does not work. (Which label1 is in the Groupbox1). when I Enable Groupbox, it fixes. But I want it to be White whether Groupbox1 is enabled or disabled.

Upvotes: 3

Views: 2370

Answers (4)

I manually changed the Groupbox's foreColor which affected the Text properties, font like so:

Changed all occurrences of Enabled false with -

            grpGeneral.ForeColor = SystemColors.GrayText;
            grpGeneral.Enabled = false;

And changed all occurrences of Enabled true with -

            grpGeneral.Enabled = true;
            grpGeneral.ForeColor = SystemColors.ActiveCaptionText;

Upvotes: 1

Kevin
Kevin

Reputation: 1472

Alternatively, you could simply not disable the GroupBox. Instead, create a method that disables all of it's children;

private void DisableChildren(Control control)
{
    foreach(var child in control.Controls.Cast<Control>().Where(child.GetType != typeof(Label) && child.GetType() != typeof(GroupBox)))
    {
        if(child.HasChildren)
        {
            DisableChildren(child);
        }
        child.Enabled = false;
    }
}

You can see I'm not disabling Labels or nested GroupBoxes.

Just use like this where you would normally disable the GroupBox;

DisableChildren(GroupBox1);

Just as a side note: The same thing happens with any container under Windows Forms (GroupBox, Panel, etc).

Upvotes: 0

Gy&#246;rgy Kőszeg
Gy&#246;rgy Kőszeg

Reputation: 18013

For some reason the fore color of the disabled controls cannot be set in the WinForms world. Instead, the disabled fore color is calculated from the BackColor

From the Label.OnPaint (by Reflector):

if (base.Enabled)
{
    TextRenderer.DrawText(e.Graphics, this.Text, this.Font, r, nearestColor, flags);
}
else
{
    Color foreColor = TextRenderer.DisabledTextColor(this.BackColor);
    TextRenderer.DrawText(e.Graphics, this.Text, this.Font, r, foreColor, flags);
}

However, you can implement a custom Label class like this:

public class MyLabel : Label
{
    private const ContentAlignment anyBottom = ContentAlignment.BottomRight | ContentAlignment.BottomCenter | ContentAlignment.BottomLeft;
    private const ContentAlignment anyMiddle = ContentAlignment.MiddleRight | ContentAlignment.MiddleCenter | ContentAlignment.MiddleLeft;
    private const ContentAlignment anyRight = ContentAlignment.BottomRight | ContentAlignment.MiddleRight | ContentAlignment.TopRight;
    private const ContentAlignment anyCenter = ContentAlignment.BottomCenter | ContentAlignment.MiddleCenter | ContentAlignment.TopCenter;

    protected override void OnPaint(PaintEventArgs e)
    {
        // drawing the label regularly
        if (Enabled)
        {
            base.OnPaint(e);
            return;
        }

        // drawing the background
        Rectangle backRect = new Rectangle(ClientRectangle.X - 1, ClientRectangle.Y - 1, ClientRectangle.Width + 1, ClientRectangle.Height + 1);
        if (BackColor != Color.Transparent)
        {
            using (Brush b = new SolidBrush(BackColor))
            {
                e.Graphics.FillRectangle(b, backRect);
            }
        }

        // drawing the image
        Image image = Image;
        if (image != null)
        {
            Region oldClip = e.Graphics.Clip;
            Rectangle imageBounds = CalcImageRenderBounds(image, ClientRectangle, RtlTranslateAlignment(ImageAlign));
            e.Graphics.IntersectClip(imageBounds);
            try
            {
                DrawImage(e.Graphics, image, ClientRectangle, RtlTranslateAlignment(ImageAlign));
            }
            finally
            {
                e.Graphics.Clip = oldClip;
            }
        }

        // drawing the Text
        Rectangle rect = new Rectangle(ClientRectangle.X + Padding.Left, ClientRectangle.Y + Padding.Top, ClientRectangle.Width - Padding.Horizontal, ClientRectangle.Height - Padding.Vertical);
        TextRenderer.DrawText(e.Graphics, Text, Font, rect, ForeColor, image == null ? BackColor : Color.Transparent, GetFormatFlags());
    }

    private TextFormatFlags GetFormatFlags()
    {
        TextFormatFlags flags = TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.TextBoxControl | TextFormatFlags.WordBreak;

        bool isRtl = RightToLeft == RightToLeft.Yes;
        var contentAlignment = TextAlign;
        if (isRtl)
            contentAlignment = RtlTranslateContent(contentAlignment);

        if ((contentAlignment & anyBottom) != 0)
            flags |= TextFormatFlags.Bottom;
        else if ((contentAlignment & anyMiddle) != 0)
            flags |= TextFormatFlags.VerticalCenter;
        else
            flags |= TextFormatFlags.Top;

        if ((contentAlignment & anyRight) != 0)
            flags |= TextFormatFlags.Right;
        else if ((contentAlignment & anyCenter) != 0)
            flags |= TextFormatFlags.HorizontalCenter;
        else
            flags |= TextFormatFlags.Left;

        if (AutoEllipsis)
            flags |= TextFormatFlags.WordEllipsis | TextFormatFlags.EndEllipsis;
        if (isRtl)
            flags |= TextFormatFlags.RightToLeft;
        if (UseMnemonic)
            flags |= TextFormatFlags.NoPrefix;
        if (!ShowKeyboardCues)
            flags |= TextFormatFlags.HidePrefix;

        return flags;
    }
}

Upvotes: 1

Vasilievski
Vasilievski

Reputation: 853

In case of WPF, put this in your XAML resources :

 <Style TargetType="GroupBox" x:Key="NameOfYourStyle">
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Foreground" Value="White"/>
            </Trigger>
        </Style.Triggers>
    </Style>

Apply the style to your GroupBox and the job will be done.

<GroupBox Style="{StaticResource NameOfYOurStyle}"/>

Dimitri

Upvotes: 1

Related Questions