Editing icons of WinForms controls.
by Alexander Kojevnikov
I love icons! I use them all the time in my WinForms applications – anywhere from buttons and tab pages to tool strip items. Icons look nice (at least they should be), but editing them is not.
In WinForms you need to edit the original image and change the corresponding .Image or .Icon properties everywhere that image is used. Some controls, such as the TabPage, can only refer to an ImageList, so you would need to amend it and be extra careful not to screw up the image indices.
I wrote a small component to ease the process (of editing, not screwing up, mind you). When ImageResource is dropped into a form it adds a new string property to Forms, Buttons, TabPages and ToolStripItems. You just need to enter the resource name of the icon and the rest is done automatically.
Here’s the code:
using System; using System.ComponentModel; using System.Reflection; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.IO; namespace Versia.Samples { [ProvideProperty("ImageResource", typeof(object))] public partial class ImageResource : Component, IExtenderProvider { private readonly Dictionary _values = new Dictionary(); private readonly Dictionary _icons = new Dictionary(); public ImageResource() { InitializeComponent(); } public ImageResource(IContainer container) { container.Add(this); InitializeComponent(); } public bool CanExtend(object target) { return target is ButtonBase || target is TabPage || target is Form || target is ToolStripItem; } [Category("Appearance")] [Description("Sets the resource name of the image to add to the control.")] [DefaultValue("")] public string GetImageResource(object target) { string value; if(_values.TryGetValue(target, out value)) { return value; } return String.Empty; } public void SetImageResource(object target, string name) { _values[target] = name; if(!_imageList.Images.ContainsKey(name)) { // Get the assembly from the resource name. Stream stream = null; foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { try { stream = assembly.GetManifestResourceStream(name); } catch(NotSupportedException) { } catch(FileNotFoundException) { } if(stream != null) break; } if(stream == null) return; // Read the image from the resource. if(name.EndsWith(".ico", StringComparison.CurrentCultureIgnoreCase)) { Icon icon = new Icon(stream); _icons[name] = icon; _imageList.Images.Add(name, icon); } else { _imageList.Images.Add(name, Image.FromStream(stream)); } } // Add the image to the control. if(target is ButtonBase) { ButtonBase button = (ButtonBase)target; button.Image = _imageList.Images[name]; } else if(target is TabPage) { // ImageList is attached to the TabControl. TabPage tabPage = target as TabPage; if(tabPage.Parent != null) { ((TabControl)tabPage.Parent).ImageList = _imageList; tabPage.ImageKey = name; } else { tabPage.ParentChanged += delegate(object sender, EventArgs e) { TabPage page = (TabPage)sender; if(page.Parent is TabControl) { ((TabControl)page.Parent).ImageList = _imageList; page.ImageKey = name; } }; } } else if(target is Form) { Form form = (Form)target; if(_icons.ContainsKey(name)) form.Icon = _icons[name]; } else if(target is ToolStripItem) { ToolStripItem item = (ToolStripItem)target; item.Image = _imageList.Images[name]; } } } }
Hello!
I think this try.
Hi,
I just get contracted by a client who needs a desktop application.
Your post save me.
Many thanks!