1

I have a WinForms project and added multiple images to the resources (project properties -> Resources). Now I have a Form1.cs, a UserControl1.cs with a .resx files, and using Assembly.GetManifestResourceNames(), it contains 3 strings namely:

1 TestApplication1.Properties.Resources.resources, 2 TestApplication1.Form1.resources 3 TestApplication1.UserControl1.resources

What I need to get now is obviously the files from #1 which contains the images I need to get. What I need to do is have a list that I can access these images through their indexes. I can access this files individually with no problem, but I have 72 images so I need them as a list. So my question is, how do I get these images in #1 as a list?

EDIT: Is there no other way as to create a list and add all of my 72 images to it? Or is there some way that I can get all of these images from the resources as a list? Also, I don't want to resort to using System.IO as I will build this application as a Class Library.

  • How do you access a single image? – Shaharyar Jan 16 '16 at 10:56
  • I mean using `Resources.Image1`, `Resources.Image2`, and so on, but I cannot do this for my 72 images so I'm asking for a way to have the images as a list. –  Jan 16 '16 at 10:59

2 Answers2

4

To get all images in a resx file, you can use either of these options:

ResourceManager.GetResourceSet

Based on Dai's answer you can use ResourceManager.GetResourceSet and then filter and shape the the result this way:

var images = Properties.Resources.ResourceManager
                       .GetResourceSet(CultureInfo.CurrentCulture, true, true)
                       .Cast<DictionaryEntry>()
                       .Where(x => x.Value.GetType() == typeof(Bitmap))
                       .Select(x => new { Name = x.Key.ToString(), Image = x.Value })
                       .ToList();

Reflection

Also, as another option you can use reflection on the type of your resource and find properties and shape the result this way:

var images = typeof(Properties.Resources)
               .GetProperties(BindingFlags.Static | BindingFlags.NonPublic |
                                                    BindingFlags.Public)
               .Where(p => p.PropertyType == typeof(Bitmap))
               .Select(x => new { Name = x.Name, Image = x.GetValue(null, null) })
               .ToList();
Community
  • 1
  • 1
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
3

Each .resx file is compiled into a single "composite" embedded *.resources resource blob that is located in your assembly. I appreciate this is confusing as it means the term "resource" is overloaded to refer to both the .resources blob, but also the individual contents of each blob.

Use the ResourceManager class to retrieve named items from within a .resources file.

Note that if you're using the .resx designer in Visual Studio then you don't need to use ResourceManager directly, you simply use the generated Resources class, like so:

using MyProject.Properties;

...

this.label1.Text = Resources.SomeLabelText;

(Where SomeLabelText is the key name)

By default, the designer-generated Resources class will be under the Properties child namespace.

To enumerate resources you'll need to use ResourceManager, like so:

ResourceSet rsrcSet = MyProject.Properties.Resources.ResourceManager.GetResourceSet( CultureInfo.CurrentCulture, false, true );

foreach( DictionaryEntry entry in rsrcSet ) {
    String name = entry.Key;
    Object resource = entry.Value;
}
Dai
  • 141,631
  • 28
  • 261
  • 374
  • Unfortunately, compiler throws an error 'System.Resources.ResourceSet.Table' is inaccessible due to its protection level –  Jan 16 '16 at 11:09
  • @EricJohnIgnacio I have revised my answer to use `ResourceSet`'s built-in `IEnumerable` implementation to get `DictionaryEntry` values. – Dai Jan 16 '16 at 11:18
  • `GetResourceSet` has 3 arguments and you didn't supply them in your code. I used `var resources = Resources.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, false, true);` and resources returned null. –  Jan 16 '16 at 11:33
  • Nevermind, I used true in the second argument and it returned what I need thanks! –  Jan 16 '16 at 11:35