Resolved Silly beginning question about dynamic resource paths for images

AverageWriter

Member
Joined
Dec 30, 2021
Messages
10
Programming Experience
Beginner
Hi!

I'm a beginner at C#, so I'm sure this is a pretty easy question for most to answer. I've searched high and low and haven't been able to come up with an answer though.

So I'm designing a program that takes a series of tiles (all saved in individual resource files from 1 to 30) and dynamically allocates them to a series of image controls.
So far so good- using global::WorldDesigner.Properties.Resources._1 (where _1 is the resource name) allows me to assign individual images.
The problem is that I need to dynamically allocate them.
In other words, I have a loop set up that needs to change that "1" to a "2" and so on, each time populating the appropriate control, until the loop finishes.
I have a pair of strings set up that combines the first part of the path (global::WorldDesigner.Properties.Resources._) with the appropriate number (1, 2, etc)

The problem I'm having is taking that finished string and then turning it back into a path, so the program thinks that my stringCombined string is a valid path to assign to the image.

What do you all think would be the best solution?

I've got a small block of code; this throws out an error.

C#:
 private void timer1_Tick(object sender, EventArgs e)
        {

            int currentTile = TileBar.Value;
            int TileIndex = 0;
            var stringLeft = TileBar.Value.ToString();
            string stringCombined = "";
            var stringCombined2 = "";
            int TileCounter = 1;

            for (TileCounter = 0; TileCounter < 30; TileCounter++) // begins the loop
            {
                
                stringCombined = "global::WorldDesigner.Properties.Resources._" + TileCounter; // this creates the icon value to assign to the designer //
                stringCombined2 = "TileRef" + stringLeft; // this gets the current icon to assign to //
                TileRef1.Image = stringCombined;  // this is where the error is thrown
            }
            
        }
 
Last edited by a moderator:
Solution
I guess I have a lot of learning to do!

It starts to compile then throws out "Resource was of type 'System.Drawing.Bitmap' instead of String - call GetObject instead"

There are a lot of nuances to this I need to learn, I guess.

Edit:

I got it working!
Along with the array code that SkyDiver mentioned, I used this, which allowed me to grab the images directly from the Resource Manager.

Thanks SkyDiver! You are awesome!

C#:
string resourceName = $"_{TileCounter}";
tiles[TileCounter - 1].Image = (Image)global::WorldDesigner.Properties.Resources.ResourceManager.GetObject(resourceName);
TileCounter++;
What is the error that you are getting?
 
Doesn't that make it obvious? You can't just convert a string into an image. Perhaps you should use Image.FromFile() to load an image from the file specified by the string, and then assign that image to that tile's Image property.
 
Now as for dynamically determining which tile to assign to. In general, as a beginner, you don't want to get involved in reflection this early in your learning journey. To accomplish what you want to do exactly as you described, you would need to use reflection. Although C# has reflection, not all languages have it, and most teachers actually discourage using it because instead of getting an error at compile time, you'll have to deal with an error at runtime.

So the way to do this without using reflection is that you would have an array of all your tiles. So assuming that your TileRef are actually PictureBoxes, you would so something like the following pseudo code:
C#:
PictureBox [] tiles =
{
    TileRef1,
    TileRef2,
    TileRef3,
    :
    TileRef29,
    TileRef30;
};

:

var rm = global::WorldDesigner.Properties.Resources.ResourceManager;
for(int i = 1; i <= 30; i++)
{
    string resourceName = $"_{i}";
    string path = rm.GetString(resourceName);
    tiles[i-1].Image = Image.FromFile(path);
}
 
Last edited:
Doesn't that make it obvious? You can't just convert a string into an image. Perhaps you should use Image.FromFile() to load an image from the file specified by the string, and then assign that image to that tile's Image property.

Ah, no, I'm not trying to convert the string into an image, it's about the string itself not being valid as a path.

I apologize for the rough terminology, as I mentioned I am still beginning.
I think the biggest problem with using an array is that eventually this program is going to have something over 400 tiles at its endpoint.

Maybe I can include an image that could show it better than I can describe.

When the program loads, the program loads the initial set of tiles (each located in the program's resource file) into the image boxes there and the scrollbar is set to 0. When the scrollbar is changed, the program loads up a new set of tiles based upon the scrollbar's position.

Or at least it's SUPPOSED to.

I mean, heck, just using " TileRef1.Image = global::WorldDesigner.Properties.Resources._1; " puts a single image where it needs to go, but individually repeating that 400 times would seem to be counterproductive.
 

Attachments

  • rows.png
    rows.png
    3.3 KB · Views: 11
Last edited:
See pseudo code in post #5. Note the use of the ResourceManager.
 
I guess I have a lot of learning to do!

It starts to compile then throws out "Resource was of type 'System.Drawing.Bitmap' instead of String - call GetObject instead"

There are a lot of nuances to this I need to learn, I guess.

Edit:

I got it working!
Along with the array code that SkyDiver mentioned, I used this, which allowed me to grab the images directly from the Resource Manager.

Thanks SkyDiver! You are awesome!

C#:
string resourceName = $"_{TileCounter}";
tiles[TileCounter - 1].Image = (Image)global::WorldDesigner.Properties.Resources.ResourceManager.GetObject(resourceName);
TileCounter++;
 
Last edited:
Solution
Back
Top Bottom