tags:

views:

32

answers:

4

I have a System.Windows.Forms.Form and want to change the Form.Icon at runtime to display a status. I've managed to load the icon from the projects ressources:

Type type = this.GetType();
System.Resources.ResourceManager resources =
    new System.Resources.ResourceManager(type.Namespace + ".Properties.Resources", this.GetType().Assembly);
this.Icon = (System.Drawing.Icon)resources.GetObject(
    type.Namespace + ".Icons." + statusText + ".ico");

But the displayed icon stays the same (design time icon) all the time. Do I have to call a method to tell the Form to apply changes? Something wrong about my usage of Form.Icon?

A: 

Yes, you have to change the icon whenever the status of your application changes.

I tested this out with a simple WinForm application:

private void button1_Click(object sender, EventArgs e)
{
    this.Icon = Properties.Resources.Gear;
}

private void button2_Click(object sender, EventArgs e)
{
    this.Icon = Properties.Resources.UAC_shield;
}

When the program is running, clicking on each button will change the form icon (and, of course, the icon in the taskbar) to the specified icon. I just picked some icons from the set that ships with Visual Studio and added them to the project's Resource file.

You should be able to add a simple method that you can call anywhere in your code which sets the icon (and you can call it from Form_Load as well):

private void ChangeIconStatus(string statusText)
{
    Type type = this.GetType();
    System.Resources.ResourceManager resources =
    new System.Resources.ResourceManager(type.Namespace + ".Properties.Resources", this.GetType().Assembly);
    this.Icon = (System.Drawing.Icon)resources.GetObject(type.Namespace + ".Icons." + statusText + ".ico");
}
Jared Harley
+2  A: 

It is unclear to me why you are doing this the hard way. Just add the icon to your resources. Project + Properties, Resource tab, arrow on Add Resource button, Add Existing File. Then you'd use it like this at runtime:

    private void button1_Click(object sender, EventArgs e) {
        this.Icon = Properties.Resources.Mumble;
    }

Where Mumble is the name of the icon.

If you are 100% sure that GetObject() doesn't return null then try setting the Icon property in the designer. If it still doesn't show up then there's something wrong with the icon format. Make sure that it doesn't have too many colors, 256 works on XP.

Hans Passant
Hi Hans, there is a type casting problem in the code above (bitmap can not be converted to Icon type, i guess). Sorry for that.
Siva Gopal
@Siva, Hans sample works without a cast for me. Maybe you haven't added your ressource as an icon?
Hinek
@Hans, thanks, I get a statusText (string) and put the icons in my resources. I want to load them via the statusText (to be flexible to add another status and icon). Your approach works, but isn't flexible ... so I have to check, what I'm doing wrong, when loading the ressource ...
Hinek
@Hinek, ya you are right.
Siva Gopal
+2  A: 

I Guess, first of all, your GetObject(...) is returning null. Thats the reason the type casting is ending up silently neither throwing error nor change the icon.

Instead,if possible, use

this.Icon = new System.Drawing.Icon(...) 

overloads and then give a try.

Siva Gopal
sounds good, do you have an example for this?
Hinek
ok, never mind, now I got it: I copied the whole namespace crap in the name of the ressource from another sample, that got me null for the GetObject() ... it works this way: this.Icon = (System.Drawing.Icon)resources.GetObject(statusText);
Hinek
That's great n cheers!!! :-)
Siva Gopal
+1  A: 

Ok, Siva and Hans where right: GetObject returned null, because the name of the ressource wasn't right. With the following change it works:

Type type = this.GetType(); 
System.Resources.ResourceManager resources = 
new System.Resources.ResourceManager(type.Namespace + ".Properties.Resources", this.GetType().Assembly);

// here it comes, call GetObject just with the resource name, no namespace and no extension
this.Icon = (System.Drawing.Icon)resources.GetObject(statusText); 

Thanks for all your help.

Hinek