Accessing resources from code for setting NotifyIcon.Icon
Asked Answered
G

2

11

I am trying to get the Icon of a NotifyIcon in WPF.

So I have added a .ico file to my solution in a Resources folder and set the build action to Resource.

I am trying to grab this resource in code behind like so:

var icon = (Icon) Application.Current.FindResource("/Resources/icon.ico")

This doesn't work.

In addition to this: Application.Current.Resources.Count returns 0.

EDIT

var i = new Icon(Application.GetResourceStream(new Uri("/systemtrayicon.ico", UriKind.Relative)).Stream);

With the icon in the root and the build action set to Resource.

Still not working.

EDIT AGAIN:

I needed to Clean the solution and rebuild as per: WPF throws "Cannot locate resource" exception when loading the image

Grounder answered 4/12, 2013 at 11:24 Comment(0)
B
11

You have to pass resourceName as a parameter to the FindResource method, not the path for the Resource. Sample code would look like:

var icon = (Icon) Application.Current.FindResource("myImage")

Please note in the above sample code "myImage" is the resource name.

Refer to Application.FindResource Method on MSDN.

You say, Application.Current.Resources.Count is Zero, that means you do not have any Resource defined in your App.xaml file.

You can add resources to App.xaml like this:

<Application.Resources>
     <Image x:Key="myImage" Source="img.png" />
</Application.Resources>

It appears that your icon is an embedded resource. FindResource cannot work with embedded resources. Set BuildAction of your icon to Resource.

Refer to this MSDN page for more reading on WPF Resources.

UPDATE

Code for accessing Embedded Resources

Assembly.GetExecutingAssembly().GetManifestResourceStream("myImg.png");

However, if you had added this image to the Resources.Resx and you should simply be able to use Resources.ResourceName.

UPDATE 2

Adding resources to App.xaml or any ResourceDictionary is better, so that you can use them as Static/Dynamic resources via StaticResource or DynamicResource markup extensions.

If you do not want to add it to App.xaml resources and still want to access it, one option as I mentioned above is to add it to the Resources.Resx and use Resources.ResourceName to refer the icon/image

Another way is to create System.Drawing.Icon by yourself, sample code:

new System.Drawing.Icon(Application.GetResourceStream(new Uri("/Resources/icon.ico")));

Personally, I would go with XAML resources and add them to App.xaml or a ResourceDictionary.

Brasil answered 4/12, 2013 at 11:44 Comment(6)
So how would I reference the .ico file from code WITHOUT adding them to the App.xaml file. Or must all resources be accessed or specified within XAML?Grounder
No, you don't have to. But preferred approach for WPF/XAML development. Since in your question you mentioned it is a Resource (not embedded resource) you could try the approach of creating Icon by yourself by calling new System.Drawing.Icon(Application.GetResourceStream(new Uri("/Resources/icon.ico")));Brasil
This is something I was already trying before your edit: new Icon(Application.GetResourceStream(new Uri("pack://application:,,,/systemtrayicon.ico")).Stream);. This is with the icon in the root and the Build Action set to Resource. Complaining that it can't find the resource.Grounder
Let me try in a sample appBrasil
Tried in a sample app, and it seem to be working. new System.Drawing.Icon(Application.GetResourceStream(new Uri("orange.ico", UriKind.Relative)).Stream);Brasil
I needed to Clean the solution and rebuild as per: #11949329Grounder
T
22

This will works 100%

ni.Icon = new Icon(Application.GetResourceStream(new Uri("pack://application:,,,<Image Location From root>")).Stream);

Example:

notify.Icon = new Icon(Application.GetResourceStream(new Uri("pack://application:,,,/images/favicon.ico")).Stream);
Transcendentalistic answered 28/12, 2013 at 10:4 Comment(1)
thanx, simple and easyCouscous
B
11

You have to pass resourceName as a parameter to the FindResource method, not the path for the Resource. Sample code would look like:

var icon = (Icon) Application.Current.FindResource("myImage")

Please note in the above sample code "myImage" is the resource name.

Refer to Application.FindResource Method on MSDN.

You say, Application.Current.Resources.Count is Zero, that means you do not have any Resource defined in your App.xaml file.

You can add resources to App.xaml like this:

<Application.Resources>
     <Image x:Key="myImage" Source="img.png" />
</Application.Resources>

It appears that your icon is an embedded resource. FindResource cannot work with embedded resources. Set BuildAction of your icon to Resource.

Refer to this MSDN page for more reading on WPF Resources.

UPDATE

Code for accessing Embedded Resources

Assembly.GetExecutingAssembly().GetManifestResourceStream("myImg.png");

However, if you had added this image to the Resources.Resx and you should simply be able to use Resources.ResourceName.

UPDATE 2

Adding resources to App.xaml or any ResourceDictionary is better, so that you can use them as Static/Dynamic resources via StaticResource or DynamicResource markup extensions.

If you do not want to add it to App.xaml resources and still want to access it, one option as I mentioned above is to add it to the Resources.Resx and use Resources.ResourceName to refer the icon/image

Another way is to create System.Drawing.Icon by yourself, sample code:

new System.Drawing.Icon(Application.GetResourceStream(new Uri("/Resources/icon.ico")));

Personally, I would go with XAML resources and add them to App.xaml or a ResourceDictionary.

Brasil answered 4/12, 2013 at 11:44 Comment(6)
So how would I reference the .ico file from code WITHOUT adding them to the App.xaml file. Or must all resources be accessed or specified within XAML?Grounder
No, you don't have to. But preferred approach for WPF/XAML development. Since in your question you mentioned it is a Resource (not embedded resource) you could try the approach of creating Icon by yourself by calling new System.Drawing.Icon(Application.GetResourceStream(new Uri("/Resources/icon.ico")));Brasil
This is something I was already trying before your edit: new Icon(Application.GetResourceStream(new Uri("pack://application:,,,/systemtrayicon.ico")).Stream);. This is with the icon in the root and the Build Action set to Resource. Complaining that it can't find the resource.Grounder
Let me try in a sample appBrasil
Tried in a sample app, and it seem to be working. new System.Drawing.Icon(Application.GetResourceStream(new Uri("orange.ico", UriKind.Relative)).Stream);Brasil
I needed to Clean the solution and rebuild as per: #11949329Grounder

© 2022 - 2024 — McMap. All rights reserved.