Windows forms access resources by name
Introduction
When items from a project resource is needed like a bitmap, Icon etc. the following can will retrieve the resource, in this case an Icon.
Icon chatIcon = Properties.Resources.Chat;
Then there are cases were a requirement specifies a resource item is needed by the resource name, learn how to get resources by name for either an icon or bitmap along with sizing a PictureBox to properly display the image. By examining the code presented other resource types like documents of various types may be read from resources and used.
Container
This class provides properties for resource name, the image and if the image is a Icon or BitMap.
public class ResourceItem
{
/// <summary>
/// Resource name
/// </summary>
public string Name { get; set; }
/// <summary>
/// Image which is either an icon or bitmap
/// </summary>
public Bitmap Image { get; set; }
/// <summary>
/// Indicates if dealing with an icon so when displaying the
/// control used to display can adjust it's size or Size mode
/// </summary>
public bool IsIcon { get; set; }
public override string ToString() => Name;
}
Class to read resources
The following class provides
- A method to obtain resource names
- A method to read resources into a list
namespace ChangeImage.Classes
{
/// <summary>
/// Read images from current project resources
/// </summary>
public class ImageHelper
{
/// <summary>
/// Get all bitmap and icon resources
/// </summary>
/// <returns></returns>
public static List<ResourceItem> ResourceItemList()
{
var items = new List<ResourceItem>();
foreach (var name in ResourceImageNames())
{
/*
* For this code sample ignore the default image
*/
if (name == "ready")
{
continue;
}
var item = new ResourceItem() {Name = name, IsIcon = false};
if (Resources.ResourceManager.GetObject(name) is Icon)
{
item.Image = ((Icon)Resources.ResourceManager.GetObject(name))?.ToBitmap();
item.IsIcon = true;
}
else
{
item.Image = (Bitmap)Resources.ResourceManager.GetObject(name);
}
items.Add(item);
}
return items;
}
/// <summary>
/// Get all resource names for icon and bitmaps
/// </summary>
/// <returns></returns>
public static List<string> ResourceImageNames()
{
try
{
var names = new List<string>();
var resourceSet = Resources
.ResourceManager
.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
names.AddRange(
from DictionaryEntry dictionaryEntry in resourceSet
where dictionaryEntry.Value is Image || dictionaryEntry.Value is Icon
select dictionaryEntry.Key.ToString());
return names;
}
catch (Exception)
{
return null;
}
}
}
}
Main access
The following singleton class provides access to resource images read once on the first time a call is made to Instance.Images.
namespace ChangeImage.Classes
{
/// <summary>
/// Provides access to resource images by loading them once
/// </summary>
public sealed class ResourceImages
{
private static readonly Lazy<ResourceImages> Lazy =
new Lazy<ResourceImages>(() => new ResourceImages());
public static ResourceImages Instance => Lazy.Value;
private List<ResourceItem> _images;
/// <summary>
/// Get all icon and bitmap images from project resources
/// </summary>
/// <returns>list of images</returns>
public List<ResourceItem> Images() => _images ??= ImageHelper.ResourceItemList();
}
}
Extension methods
Use these extension methods to get only Icon or BitMap images from resources read from ImageHelpers.ResourceList called from ResourceImages.Instance.Images.
namespace ChangeImage.Extensions
{
public static class ResourceItemExtensions
{
/// <summary>
/// Return resources of type Icon
/// </summary>
/// <param name="sender"></param>
/// <returns>list of icons or an empty list</returns>
public static List<ResourceItem> Icons(this List<ResourceItem> sender) =>
sender.Where(item => item.IsIcon).ToList();
/// <summary>
/// Return resources of type Bitmap
/// </summary>
/// <param name="sender"></param>
/// <returns>list of bitmaps or an empty list</returns>
public static List<ResourceItem> BitMaps(this List<ResourceItem> sender) =>
sender.Where(item => !item.IsIcon).ToList();
}
}
Example usage
A form is setup with three ListBox controls to display images while the topmost ListBox has a button associated to display images in a PictureBox while the other two are showing icon and bitmap images to demonstrate the two language extensions above. Note the method ChangeFromAllImages method would normally be in the button click which would made it difficult (would need to use PerformClick for that button) to display the first image on form shown event.
using System;
using System.Windows.Forms;
using ChangeImage.Classes;
using ChangeImage.Extensions;
namespace ChangeImage
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
Shown += OnShown;
}
private void OnShown(object? sender, EventArgs e)
{
var allImages = ResourceImages.Instance.Images();
/*
* Do we have images from resources?
*/
if (allImages is null)
{
MessageBox.Show("No images located");
SelectFromAllImagesButton.Enabled = false;
}
AllImagesListBox.DataSource = allImages;
ChangeFromAllImage();
IconListBox.DataSource = allImages.Icons();
BitmapListBox.DataSource = allImages.BitMaps();
}
private void SelectFromAllImagesButton_Click(object sender, EventArgs e)
{
ChangeFromAllImage();
}
private void ChangeFromAllImage()
{
if (AllImagesListBox.SelectedIndex <= -1) return;
var item = (ResourceItem) AllImagesListBox.SelectedItem;
pictureBox1.SizeMode = item.IsIcon ? PictureBoxSizeMode.Normal : PictureBoxSizeMode.Zoom;
pictureBox1.Image = item.Image;
}
}
}
Summary
Code presented provides access to resources in a Windows form project.
Using in a project
- Copy classes under the classes folder, change the namespace to match the current project.
- Copy the class under Extensions, change the namespace to match the current project.
- Use the code in the form to implement
Source code
Clone this GitHub repository in Visual Studio or with Git Desktop.
See also
Localization for Windows Universal apps
String and Embedded Resources inside Windows Store App
Windows forms overview
C# Singletons