views:

804

answers:

3

Within a Visual Basic Project I have added a resource file (resx) that contains a bunch of images.

Now I want to query the names of the images. If I open the resx file in the designer view in the Visual Studio IDE and select an image, the property grid shows me a name property (defaults to "filename without extension but can be changed).

The background is that I have a imagelist that is created at runtime and populated with the images from the resource file. To be able to access these images by the key, I have to set it.

My code looks like this (everything hard coded):

Dim imagelist as new Imagelist
imageList.Images.Add("A", My.Resources.MyImages.A)
imageList.Images.Add("B", My.Resources.MyImages.B)
imageList.Images.Add("C", My.Resources.MyImages.C)
imageList.Images.Add("D", My.Resources.MyImages.D)
imageList.Images.Add("E", My.Resources.MyImages.E)
....
imageList.Images.Add("XYZ", My.Resources.MyImages.XYZ)

And I want to achive this:

Dim imagelist as new ImageList

For Each img in GetMeAllImagesWithNameFromMyResourceFile
    imageList.Images.Add(img.Name, img.ImageFile)
Next

where Name is a string and ImageFile a System.Drawing.Bitmap

A: 

Try something like this:

Dim reader As New ResXResourceReader(resxFilePath)

Dim en As IDictionaryEnumerator
en = reader.GetEnumerator()

While en.MoveNext()
    Console.WriteLine("Resource Name: [{0}] = {1}", en.Key, en.Value)
End While

reader.Close()

You can find more examples that could help you out at this link. The examples are written in C#, but it's not very hard to modify them for vb.net

alex
I suppose he wants to load embedded resources. The above code works for external RESX files.
Thorsten Dittmar
A: 

The following is written in C#, you should be able to translate this to VB easily.

Assembly executingAssembly = GetExecutingAssembly();

foreach (string resourceName in executingAssembly.GetManifestResourceNames())
{
    Console.WriteLine( resourceName );
}

Now that you have all the resource names, you can iterate over the list and do something like:

foreach(string s in executingAssembly.GetManifestResourceNames())
{
    if (s.EndsWith(".bmp"))
    {
        imgStream = a.GetManifestResourceStream(s);
        if (imgStream != null)
        {                    
            bmp = Bitmap.FromStream(imgStream) as Bitmap;
            imgStream.Close();
        }   
    }
}

I have not tried this, but it should work.

Thorsten Dittmar
GetManifestResourceNames enumerates all my Resources (e.g. [WindowsApplication1.Images.resources |WindowsApplication1.Resources.resources |WindowsApplication1.Form1.resources] ). Not what I want.
SchlaWiener
+1  A: 

See if this piece of code helps.

    Dim runTimeResourceSet As Object
    Dim dictEntry As DictionaryEntry

    runTimeResourceSet = My.Resources.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, False, True)
    For Each dictEntry In runTimeResourceSet
        If (dictEntry.Value.GetType() Is GetType(Icon)) Then
            Console.WriteLine(dictEntry.Key)
        End If
    Next

I have used Icon as an example, which you will have to change if you are using Bitmap.

EDIT: You will have to use reference of dictEntry.Value & see how it can be used for adding it to imagelist.

shahkalpesh
Works great, exactly what I wanted. Just 2 small changes: First: GetResourceSet's second parameter should be true (to get a reference even if the Resouce hasn't been loaded yet). Second: Icon.GetType() will not work because you haven't instanced it, it should be GetType(Icon) instead. Maybe you could edit your post to correct this.
SchlaWiener
If I remember correctly, this piece of code works with Icon.GetType(). I will change it to have GetType(Icon) as per your suggestion.
shahkalpesh
It will work in a Windows Form, because you have a Form1.Icon property that returns the actual Icon of the form. But GetType(Icon) is the clean solution.
SchlaWiener