• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 994
  • Last Modified:

How to change button's foreground color when disabled?

I have several dark colored (Desktop color) buttons that, when disabled, show black text.  Is there a way to change this foreground color to another color (like grey)?
0
rmmarsh
Asked:
rmmarsh
  • 14
  • 13
3 Solutions
 
Fernando SotoCommented:
Hi rmmarsh,

When a button is disabled there is only on way that I know of to do what you want and that is to subclass the button and change the behavior of it. The code snippet below show how this can be done.

Regards,
Fernando
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel; 
namespace WindowsFormsApplication30
{
    class ModifiedBtnCtl : System.Windows.Forms.Button
    {
        // Show the property in the Properties window
        private Color foreColorDisabled;
        [Browsable(true),
         Description("Text color when control is disabled")
        ]
        public Color ForeColorDisabled
        {
            get { return foreColorDisabled; }
            set { foreColorDisabled = value; }
        } 
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            // Calling the base class OnPaint
            base.OnPaint(e);
            // If the button is disabled then panit.
            if(this.Enabled == false )
            {
                // Setup the Formatting for the text
                StringFormat formatText = new StringFormat(StringFormatFlags.NoClip);
                formatText.LineAlignment = StringAlignment.Center;
                formatText.Alignment = StringAlignment.Center;
                // Drawing the button yourself. 
                Brush brush = new SolidBrush(this.BackColor);          
                e.Graphics.FillRectangle(brush, e.ClipRectangle);
                // Draw the line around the button
                e.Graphics.DrawRectangle(new Pen(Color.Black, 1), 0, 0, this.Width - 1, this.Height - 1);
                // Draw the text in the button
                e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(foreColorDisabled),
                    new RectangleF(0.0F, 0.0F, this.Width, this.Height), formatText);
            }
        }
    }
}

Open in new window

0
 
rmmarshAuthor Commented:
Hi Fernando... thanks for the code... however, this is what I get when I try to run it in the debugger:
System.Resources.MissingManifestResourceException was unhandled
  Message="Could not find any resources appropriate for the specified culture or the neutral culture.  Make sure \"Prager_Book_Inventory.mainForm.resources\" was correctly embedded or linked into assembly \"PragerInventory\" at compile time, or that all the satellite assemblies required are loadable and fully signed."
  Source="mscorlib"
  StackTrace:
       at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
       at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
       at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
       at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture, Boolean wrapUnmanagedMemStream)
       at System.Resources.ResourceManager.GetObject(String name)
       at Prager_Book_Inventory.mainForm.InitializeComponent() in J:\C# Applications\Inventory Program\Prager Book Maintenance\Main Form.Designer.cs:line 1465
       at Prager_Book_Inventory.mainForm..ctor() in J:\C# Applications\Inventory Program\Prager Book Maintenance\Main Form.cs:line 161
       at Prager_Book_Inventory.Prager.Main() in J:\C# Applications\Inventory Program\Prager Book Maintenance\Program.cs:line 62
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 



0
 
Fernando SotoCommented:
Remove this statement and recompile:

using System.Linq;

The above statement is only in .Net 3.5
0
Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

 
rmmarshAuthor Commented:
Never had it in there...

#region Using directives
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net.Mail;
using System.ServiceProcess;
using System.Threading;
using System.Windows.Forms;
using FirebirdSql.Data.FirebirdClient; 
//using Google;
#endregion
 
namespace Prager_Book_Inventory
{
    class ModifiedBtnCtl : System.Windows.Forms.Button
    {
        // Show the property in the Properties window
        private Color foreColorDisabled;
        [Browsable(true), Description("Text color when control is disabled")]
        public Color ForeColorDisabled
        {
            get { return foreColorDisabled; }
            set { foreColorDisabled = value; }
        }
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            // Calling the base class OnPaint
            base.OnPaint(e);
            // If the button is disabled then panit.
            if (this.Enabled == false)
            {
                // Setup the Formatting for the text
                StringFormat formatText = new StringFormat(StringFormatFlags.NoClip);
                formatText.LineAlignment = StringAlignment.Center;
                formatText.Alignment = StringAlignment.Center;
 
                // Drawing the button yourself. 
                Brush brush = new SolidBrush(this.BackColor);
                e.Graphics.FillRectangle(brush, e.ClipRectangle);
                // Draw the line around the button
                e.Graphics.DrawRectangle(new Pen(Color.Black, 1), 0, 0, this.Width - 1, this.Height - 1);
                // Draw the text in the button
                e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(foreColorDisabled), new RectangleF(0.0F, 0.0F, this.Width, this.Height), formatText);
            }
        }
    }
 
 
    public partial class mainForm : Form
    {
        static IFormatProvider localCulture = System.Globalization.CultureInfo.CurrentCulture;  //  get current culture
        public static DateTime compileDate = DateTime.Parse("15 Nov 2008 5:43 AM", localCulture);
        //public static string versionNumber = "8.8 " + compileDate.ToString("dd-MMM-yyyy");
        public static string versionNumber = "8.8.7 BETA "; // + compileDate.ToString("dd-MMM-yyyy");

Open in new window

0
 
Fernando SotoCommented:
Hi rmmarsh;

Looking over the error message above the error seems to be coming from Missing Manifest Resource Exception when the program first runs and I do not see it pointing to the Button subclass.

As Far as the button control code I posted I have tried it and works on my system. Once you have compiled the class you will find a control in the ToolBox window in a tab with the same name as the Project with the control name ModifiedBtnCtl. You need to drag one of these Button control to get the new behavior.

Fernando
0
 
rmmarshAuthor Commented:
Hi Fernando... if I comment out your code it compiles correctly... hmmm... can it be outside of the mainForm?
0
 
rmmarshAuthor Commented:
I ment to say:  is the placement of the code correct?  (see post #22968735)
0
 
Fernando SotoCommented:
Because it is a control and creates its own dll try placing it in its own file.
0
 
rmmarshAuthor Commented:
Compiled it, added the .dll to my solution as a reference, added a tab to the toolbox but am unable to find the ModifiedBtnCtl... am I missing a step?
0
 
Fernando SotoCommented:
When you compile this class with the project it is going to be used with the IDE automatically adds it to the Toolbox in a tab with the same name as the project. The all that is needed is to drag the button ModifiedBtnCtl from the Toolbox to the form.

What version of VS .Net are you using?
0
 
rmmarshAuthor Commented:
VS 2008 C# Express
0
 
rmmarshAuthor Commented:
When I try to browse to include the .dll from the Toolbox, it tells me that "there are no components in the .dll that can be placed onthe Toolbox:.
0
 
Fernando SotoCommented:
Hi rmmarsh;

Try and follow these steps and see if it works for you.

1.  Create new Windows Form Application.
2.  In the Solution Explorer window right click on Project name then select Add | class
3.  Give the new class a name in the Add New Item window, I called it ModifiedBtnCtl but it can be any valid class name.
4:  Copy the class code for ModifiedBtnCtl from my previous post make sure to inherrit the class from System.Windows.Forms.Button and add the three using statements to the top of the file:
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
5.  Now compile the code without adding anything else to it.
6.  Now switch to the Toolbox windows and tou will see a new Tab with the current project name with a new control in it call ModifiedBtnCtl or what ever you gave as a name in step 3 above. Note that you did not have to locate the control and add it to the Toolbox the IDE does that.
7.  Drag the control onto the form as you would any control in the Toolbox.
8.  With the control selected open the Properties window and set the ForeColorDisable to a color you wish the text to have when the control is disabled.
9.  Add another button control either standard or ModifiedBtnCtl and in its click event place this code.
if (modifiedBtnCtl1.Enabled)
{
    modifiedBtnCtl1.Enabled = false;
}
else
{
    modifiedBtnCtl1.Enabled = true;
}

The above code assumes that the first button placed on the form was modifiedBtnCtl1 and the code was place in the second button.
10. Compile and run. When you click on the second button it will disable the modifiedBtnCtl1 button when you click it again it will enable the button.

Fernando
0
 
Fernando SotoCommented:
Hi rmmarsh;

I have upload a test program that I used. Click on the below link if it asks for a Username and password it is the same as you use on this site. Also I made one small modification to the sub-class button control, I changed this line:

StringFormat formatText = new StringFormat(StringFormatFlags.NoClip);

to this:

StringFormat formatText = new StringFormat(StringFormatFlags.LineLimit);

So that if the text in the control does not fit on one line it will clip it so that you do not get two lines in the control.

https://filedb.experts-exchange.com/incoming/ee-stuff/7364-WindowsFormsApplication32.zip

Fernando
0
 
Fernando SotoCommented:
Hi rmmarsh;

Be aware that the program I have uploaded, you may not be able to open in the express version seeming it was created in the Team edition.

Fernando
0
 
Fernando SotoCommented:
Hi rmmarsh,

Any progress.

Fernando
0
 
rmmarshAuthor Commented:
Hi Fernando.. I had a change of direction temporarily... I found that if I set everything the default (System or the other one which I can't remember), and then give instructions on how to change the colors to the viewers liking using the Properties of the desktop, it would be better.  However, when using the system settings, you can't change the background.. so I'm going to give your code a go, hopefully this week...
Thanks so much for your effort; I'll keep you posted because I still need to accomplish it, only under different circumstances.
0
 
Fernando SotoCommented:
OK  ;=)
0
 
rmmarshAuthor Commented:
Hi Fernando... downloaded the code, compiled it on VS 2008 Express and it appears to work... (I just tried to set the background color manually, not programatically)... so, it's off to try to integrate it into my program over the next several days (due to time constraints)...
rmmarsh (rolf)
0
 
Fernando SotoCommented:
Very good.  ;=)
0
 
rmmarshAuthor Commented:
Argghhhh!  I compiled the code as a Class Library... got the .dll, no problems... added the .dll to my project as a reference... no problem.... the ModifiedBtnCtrl still does NOT show up in the toolbox, and it's driving me crazy!
0
 
rmmarshAuthor Commented:
OK... I added it to my original project, built the ModifiedBtnCtrl and now I see it in the toolbox.  However, it is disabled... why?
0
 
Fernando SotoCommented:
Seeming you added a dll for that control in the Toolbox already from the previous post ID: 22988705,
there might be a conflict with the code added in the last post. Try deleting the control in the Toolbox and then re-compile the code and see what happens.
0
 
rmmarshAuthor Commented:
I removed the reference to the dll, then added the source code to the current solution as a project; did a build and it and it shows up in the toolbox.  However, It's disabled; can't do anything with it... any idea why it's disabled?
0
 
Fernando SotoCommented:
You state, "then added the source code to the current solution as a project".  Just add the class as a new class to the current solution and do not create a project to place it in. See if that works.
0
 
rmmarshAuthor Commented:
That did it!  Thank you so much...  now one more small question:  is there an easy way to replace the existing button with this one without killing the app?
0
 
Fernando SotoCommented:
What you can do is try and do a find and replace of the button name. So for example if you have a button name Button1 and you want to replace it with ModifiedBtnCtrl do a Replace Button1 with ModifiedBtnCtrl1. Now be careful when you do this because if you have multiple forms there may be more then 1 Button1 and remember that when you make changes like this to the form you need to do the same changes to the Designer.cs file for the form as well.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 14
  • 13
Tackle projects and never again get stuck behind a technical roadblock.
Join Now