One of the nicest things about Visual Studio and the .NET language is choice. You have plenty of choices, plenty of options, and plenty of different ways to confuse and confound yourself. Take, for instance, icons/images as “labels” for buttons: what’s the best way to do that?
At face value, there are two options, either of which should theoretically work just fine, and get what you need: Image Lists and Resources (resx files). Technically, there’s even a third option: compiling local resources directly into your application. Anyway if this all sounds like Greek to you, no worries, here’s the low-down on these two (three) different ways of adding an image to your file.
1) Resources (.resx)
The default (and textbook method) of including images in your project is with the use of Resource Files. Resource files come with every project and don’t require adding an object, declaring scopes, or cross-class access to use the same images over and over again. They get compiled right into your code, and you reference them directly from an object. They’re defined in a $PROJECT.resx file, and contained in raw format in the /Resources directory of your project – though they’re later compiled into the .exe and made invisible.
Resource files can be really valuable if you re-use images, try to make minimalist applications, or are otherwise interested in direct access to your code. But they do have some major drawbacks that’ll become apparent the minute you try working with a large project. For one thing, you can’t dynamically update references to indexes of Resource Files. If you rename or otherwise modify an entry such that the name of the resource is modified, you’ll have to go through your code and change all references one-by-one.
More importantly, Visual Studio doesn’t handle resources the way it should. When you delete an entry from the .resx file it’s not really gone! You’ll have to manually delete it from the project folder as well. Even worse, when you delete a .resx entry, your project will no longer load. Visual Studio will not delete references to .resx entries, and as result, it’ll try to access a file that doesn’t exist. You won’t be able to edit your form in the designer, instead having to open the .designer.vb file and deleting the references manually afterwards. It doesn’t even check for duplicate names, so you’ll end up over-writing existing data and corrupting your .resx file too if you try (and succeed) to re-add an existing resource.
2) Image Lists
Image Lists are nifty objects introduced in Visual Studio that let you group local resources (namely, images) in an “album” of sorts, then access them (assign the images to various buttons and forms) by specifying the name of the Image List and either the index (number/id) of the individual image or the name (same as the file name).
Benefits of Image Lists come from its flexibility. You create an Image List, add images to it, and link other objects to the Image List itself. After that, you can change the contents of the Image List, reorder them, replace them, switch names, remove entries, etc. from the Image List and never have to go back to the referencing objects to update the entries there. Even more useful is the versatility of Image Lists: you can use them to add just about any type of image/media file recognized by the Windows API, and most importantly: you can use 32-bit .ico files without the ugly shadowing. With Image Lists you can even resize icons/images without having to create new copies or define new methods.
Image Lists have one drawback: they corrupt the rendering of certain hi-res 32-bit .ico files. You’ll notice tiny “blocks” or “squares” appearing on your images as a result of something in how Image Lists render .ico files – so just be careful before jumping for joy at finding a .NET component that (appears to) correctly render 32-bit hi-res icon files.
If you want to save up on the memory usage and like complete control, then you should be using resources files. If you’re not, then there’s absoloutely no reason to be using them: Image Lists are the way to go. It doesn’t matter if you have to re-define already existing images and waste a couple of KB just so you don’t have cross-form access to the same Image List, it’s still worth it. You’ll get more reliable results, better image manipulation, and code that works almost no matter what you do. Plus, you’ll save up on the size of all those dead & unreferenced images you’d have by using Resource Files.