Introduction
Tool strips are a fantastic asset because they provide a tidy and user-friendly interface for the user. It is possible to add images to many of the different tool strip items. It is even possible to force such items to appear larger by adjusting the property ImageScalingSize, however at the cost of pixelisation.
Usually it is desirable to make our applications as accessible as possible. Larger tool strip items are fantastic for those with poorer sight, or even those who just simply enjoy the quality of larger icons. Unfortunately, the standard ToolStrip class does not provide Icon support. When an icon is specified, it is converted into an Image instance. Thus the benefits of using an icon are lost.
So I decided that it would be a nice idea to add multi-image support to the ToolStrip control. Whilst my primary focus was on adding some support for Icon, I thought it more desirable to generalize this by using the two interfaces IImageProvider and IMultipleImageProvider.
Design
When MultipleImageToolStrip is being updated, it calls upon available IImageProvider's to acquire images of the required size.
An IImageProvider exposes the two methods IsImageSupported and GetImage. When multiple icon providers are available, it is possible to access the required icon using a key. In the code supplied with this article, the key represents a ToolStripItem. The following illustration provides an overview of the design using a UML class diagram.
When no IImageProvider is available, the original ToolStripItem is maintained and stretched where necessary to match the overall tool strip size.
For my extension, I decided that four discreet sizes would ease the implementation of custom image providers. The available sizes are: Small (16 x 16), Medium (24 x 24), Large (32 x 32), and ExtraLarge (48 x 48). When the requested image size is not available, a default icon can be automatically substituted if the MultipleImageToolStrip.UseUnknownImageSizeIcon is set to true.
Images are selected as follows:
- If an image provider is available from within the tool strip:
- If the required image size is supported, that image is acquired.
- If the required image size was not supported and
UseUnknownImageSizeIcon is set, the default image provider is utilized.
- When no image can be acquired using those criteria, the original image is simply stretched to match that of the scaled buttons.
- If the above fails and the item is itself an
IImageProvider then it is used to acquire the required image.
- Finally if the items
ToolStripItem.Tag is an IImageProvider then it is used to acquire the required image.
Using the Code
It is always a good idea to backup your project before trying something new!
To use the attached code simply:
- Add the source files to your project.
- Recompile your project.
- Drag
MultipleImageToolStrip onto your Form or UserControl from the tool box.
- Add some buttons.
- You should now have a
ToolStrip which behaves much the same as before.
If you want to convert an existing ToolStrip into a MultipleImageToolStrip:
- Find the ".designer.cs" file which is associated with your form or control.
- Open it up and replace instances of
ToolStrip with MultipleImageToolStrip.
To make items automatically resizable, add a handler for your form's (or control's) Load event. Take a look below for an example of how to do this:
private void Form1_Load(object sender, EventArgs e)
{
this.iconToolStrip.BeginUpdateImages();
this.iconToolStrip.AssignImage(toolStripBack, new IconImageProvider(
Resources.arrow_left));
this.iconToolStrip.AssignImage(toolStripForward, Resources.arrow_right);
this.iconToolStrip.AssignImage(toolStripHome, Resources.home);
this.iconToolStrip.AssignImage(toolStripStop, Resources.stop);
this.iconToolStrip.EndUpdateImages();
this.iconToolStrip.ImageSize = ImageSize.Medium;
}
When a tool strip item is permanently removed, the associated IImageProvider must also be manually removed. This decision was made because often an item is only removed temporarily and then reinserted.
If you always want to remove an associated IImageProvider when a tool item is removed, add a handler for the MultipleImageToolStrip.ItemRemove event:
private void iconToolStrip_ItemRemoved(object sender, ToolStripItemEventArgs e)
{
this.iconToolStrip.RemoveImage(e.Item);
}
Alternatively the associated provider can be removed along with the item:
public void RemoveToolStripItem(ToolStripItem item)
{
this.iconToolStrip.Items.Remove(item);
this.iconToolStrip.RemoveImage(item);
}
Points of Interest
The fantastic icons used in the demo application were kindly provided by glyFX from their free 'Vista Common' icon set. The required icons were combined together using the free IcoFX tool.
History
- 16th June, 2008: Original version posted
- 3rd August, 2009: Demo and source files updated
- Member Guy..L found a performance issue when changing multiple tool icons in sequence. This problem should now have been resolved.
|
|
 |
 | I am getting an error when building the project nmichalo | 0:21 7 Jan '10 |
|
 |
I have added the 2 classes from your source code in my project, but when I attempt to build the project I get this error
Error 1 The type or namespace name 'Properties' does not exist in the namespace 'IconToolStrip' (are you missing an assembly reference?) C:\Visual Studio 2008\Projects\test\test\IconToolStrip.cs 8 21 test
Any suggestions?
|
|
|
|
 |
|
 |
The "Properties" namespace is a custom namespace for resource that is used in the demonstration project. I recommend that you take a look at the "Demo" zip instead as everything is already set up there.
Please let me know if you are still having problems.
Many thanks, Lea Hayes
|
|
|
|
 |
 | IDE reports that error occurs on the line "using IconToolStrip.Properties;".Why? GoodLucy | 3:31 25 Sep '09 |
|
 |
It is not found "Prooerties" in the namespace of IconToolStrip. Someone can help me?
|
|
|
|
 |
|
 |
Do you mean "Prooerties" or "Properties"?
Could you provide steps that I can follow to reproduce the same problem?
i.e.
Step 1. Download "demo project" Step 2. ...
Thanks, Lea Hayes
|
|
|
|
 |
 | ToolStripManager for MultipleImageToolStrip Guy..L | 2:25 3 Aug '09 |
|
 |
I was surprised to find that ToolStripManager kind of works for MultipleImageToolStrip.
Do you suppose there is a way to "extend" ToolStripManager to store settings for MultipleImageToolStrip.ImageSize as well?
Guy..L
|
|
|
|
 |
|
 |
This isn't a feature that I want to add to the control itself, but here are some instructions that you can follow to add this functionality:
Step 1. Use the following version of "IconToolStrip.cs": Step 2. In your form designer set the "SaveSettings" property to "True". Step 3. Build & Run.
This code does not use the "ToolStripManager" class, I don't think that there is any easy way of extending this. Instead the following uses the application settings file. Please note that if two forms have a toolstrip of the same Name, they WILL conflict.
Let me know how you get on!
IconToolStrip.cs: =================
using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Drawing; using System.Runtime.Serialization; using System.Windows.Forms;
using IconToolStrip.Properties;
namespace IconToolStrip { public enum ImageSize { /// <summary> /// An image of 16x16 pixels. /// </summary> Small, /// <summary> /// An image of 24x24 pixels. /// </summary> Medium, /// <summary> /// An image of 32x32 pixels. /// </summary> Large, /// <summary> /// An image of 48x48 pixels. /// </summary> ExtraLarge, }
/// <summary> /// Implementations of this interface must indicate whether or not the /// requested image size is supported. A default image override could /// be enforced should the provider report with no support. /// </summary> public interface IImageProvider { #region Methods
/// <summary> /// Queries the image provider for support of a specific size. /// </summary> /// <param name="size">Indicated image size.</param> /// <returns>Returns true when the requested size is supported.</returns> bool IsImageSupported(ImageSize size);
/// <summary> /// Fetches an image of the requested size. /// </summary> /// <param name="size">Size of image to obtain.</param> /// <returns>If supported, returns requested image. A value of null /// indicates that the requested size is not supported.</returns> Image GetImage(ImageSize size);
#endregion }
/// <summary> /// Implementations of this interface can provide access to multiple /// different images of multiple different sizes. A default image override /// could be enforced should the provider report with no support. /// </summary> public interface IMultipleImageProvider { #region Methods
/// <summary> /// Queries the image provider for support of a specific size. /// </summary> /// <param name="key">Key used to identify an image.</param> /// <param name="size">Indicated image size</param> /// <returns>Returns true when the requested size is supported.</returns> bool IsImageSupported(object key, ImageSize size);
/// <summary> /// Fetches an image of the requested size. /// </summary> /// <param name="key">Key used to identify an image.</param> /// <param name="size">Size of image to obtain.</param> /// <returns>If supported, returns requested image. A value of null /// indicates that the requested size is not supported.</returns> Image GetImage(object key, ImageSize size);
#endregion
#region Properties
/// <summary> /// Gets count of registered image providers. /// </summary> int ImageProviderCount { get; }
#endregion }
/// <summary> /// Provides a collection which pairs image providers with a key object. /// The collection can be used to provide access to different images of /// different sizes. /// </summary> public class ImageProviderCollection : Dictionary<object, IImageProvider>, IMultipleImageProvider { #region Construction and destruction
public ImageProviderCollection() : base() { }
public ImageProviderCollection(int capacity) : base(capacity) { }
public ImageProviderCollection(ImageProviderCollection collection) : base(collection) { }
public ImageProviderCollection(SerializationInfo info, StreamingContext context) : base(info, context) { }
#endregion
#region IMultipleImageProvider Members
/// <summary> /// Queries the image provider for support of a specific size. /// </summary> /// <param name="key">Key used to identify an image.</param> /// <param name="size">Indicated image size</param> /// <returns>Returns true when the requested size is supported.</returns> public bool IsImageSupported(object key, ImageSize size) { if (!this.ContainsKey(key)) return false; return this[key].IsImageSupported(size); }
/// <summary> /// Fetches an image of the requested size. /// </summary> /// <param name="key">Key used to identify an image.</param> /// <param name="size">Size of image to obtain.</param> /// <returns>If supported, returns requested image. A value of null /// indicates that the requested size is not supported.</returns> public Image GetImage(object key, ImageSize size) { if (!this.ContainsKey(key)) throw new NullReferenceException(); return this[key].GetImage(size); }
/// <summary> /// Gets count of registered image providers. /// </summary> int IMultipleImageProvider.ImageProviderCount { get { return Count; } }
#endregion }
/// <summary> /// Allows an icon to be used to provide images of different sizes. /// </summary> public class IconImageProvider : IImageProvider { #region Construction and destruction
public IconImageProvider(Icon icon) { this.m_sourceIcon = icon; }
public IconImageProvider(System.IO.Stream stream) { this.m_sourceIcon = new Icon(stream); }
public IconImageProvider(string fileName) { this.m_sourceIcon = new Icon(fileName); }
public IconImageProvider(Type type, string resource) { this.m_sourceIcon = new Icon(type, resource); }
#endregion
#region Global Utility Methods
/// <summary> /// A utility method which transforms an enumerated image value into /// a two-dimensional size. /// </summary> /// <param name="size">Requested image size.</param> /// <returns>Returns a two-dimensional size.</returns> public static Size GetIconSize(ImageSize size) { switch (size) { case ImageSize.Small: return new Size(16, 16); case ImageSize.Medium: return new Size(24, 24); case ImageSize.Large: return new Size(32, 32); case ImageSize.ExtraLarge: return new Size(48, 48); default: throw new NotSupportedException("Invalid image size requested."); } }
#endregion
#region Events
/// <summary> /// Raised when the icon property is changed. /// </summary> public OldNewEventHandler<Icon> IconChanged;
/// <summary> /// Invoked the 'IconChanged' event. /// </summary> /// <param name="e">Provides access to old and new icons.</param> public virtual void OnIconChanged(OldNewEventArgs<Icon> e) { if (this.IconChanged != null) this.IconChanged(this, e); }
#endregion
#region IImageProvider Members
/// <summary> /// Queries the image provider for support of a specific size. /// </summary> /// <param name="size">Indicated image size.</param> /// <returns>Returns true when the requested size is supported.</returns> public bool IsImageSupported(ImageSize size) { return true; }
/// <summary> /// Fetches an image of the requested size. /// </summary> /// <param name="size">Size of image to obtain.</param> /// <returns>If supported, returns requested image. A value of null /// indicates that the requested size is not supported.</returns> public Image GetImage(ImageSize size) { Icon desiredSize = new Icon(SourceIcon, IconImageProvider.GetIconSize(size)); return desiredSize.ToBitmap(); }
#endregion
#region Properties
/// <summary> /// Gets or sets the source icon. /// </summary> public Icon SourceIcon { get { return this.m_sourceIcon; } set { if (value != this.m_sourceIcon) { Icon oldIcon = this.m_sourceIcon; this.m_sourceIcon = value; OnIconChanged(new OldNewEventArgs<Icon>(oldIcon, value)); } } }
#endregion
#region Attributes
private Icon m_sourceIcon;
#endregion }
/// <summary> /// Provides event handlers with the current and proposed image sizes. /// Event handlers can decide whether or not to cancel this procedure. /// </summary> public class ImageSizeChangingEventArgs : CancelEventArgs { #region Construction and destruction
public ImageSizeChangingEventArgs(ImageSize oldValue, ImageSize newValue) : base(false) { this.m_currentValue = oldValue; this.m_newValue = newValue; }
#endregion
#region Properties
/// <summary> /// Gets the current image size. /// </summary> public ImageSize CurrentValue { get { return this.m_currentValue; } }
/// <summary> /// Gets the proposed image size. /// </summary> public ImageSize NewValue { get { return this.m_newValue; } }
#endregion
#region Attributes
private ImageSize m_currentValue; private ImageSize m_newValue;
#endregion }
public delegate void ImageSizeChangingEventHandler(object sender, ImageSizeChangingEventArgs e);
/// <summary> /// This toolstrip implements the multiple image provider interface and thus /// provides support for automatic image changes based upon the selected /// image size. /// </summary> public class MultipleImageToolStrip : ToolStrip, IMultipleImageProvider, IImageProvider, IPersistComponentSettings { #region Construction and destruction
public MultipleImageToolStrip() { this.m_imageProvider = new ImageProviderCollection(); this.m_defaultProvider = this;
this.m_settings = new PersistentIconToolStripSettings((this as IPersistComponentSettings).SettingsKey); }
#endregion
#region Constants
public const ImageSize DefaultImageSize = ImageSize.Small;
#endregion
#region Events
/// <summary> /// Raised when image size is about to be changed. /// </summary> public event ImageSizeChangingEventHandler ImageSizeChanging; /// <summary> /// Raised when image size is changed. /// </summary> public event OldNewEventHandler<ImageSize> ImageSizeChanged; /// <summary> /// Raised when the property 'UseUnknownImageSizeIcon' is changed. /// </summary> public event EventHandler UseUnknownImageSizeIconChanged;
/// <summary> /// Invokes the 'ImageSizeChanging' event handler. /// </summary> /// <param name="e">Event arguments.</param> /// <returns>Returns true when proposed change is accepted.</returns> protected virtual bool OnImageSizeChanging(ImageSizeChangingEventArgs e) { if (e.Cancel) return false;
ImageSizeChangingEventHandler handler = this.ImageSizeChanging; if (handler != null) { handler(this, e); return !e.Cancel; }
return true; }
/// <summary> /// Invokes the 'ImageSizeChanged' event handler. /// </summary> /// <param name="e">Event arguments.</param> protected virtual void OnImageSizeChanged(OldNewEventArgs<ImageSize> e) { OldNewEventHandler<ImageSize> handler = this.ImageSizeChanged; if (handler != null) this.ImageSizeChanged(this, e); }
/// <summary> /// Invokes the 'UseUnknownImageSizeIconChanged' event handler. /// </summary> /// <param name="e"></param> protected virtual void OnUseUnknownImageSizeIconChanged(EventArgs e) { // Refresh toolstrip images from providers? if (!IsUpdatingImages) RefreshItemImages();
// Raise the associated event handler. EventHandler handler = this.UseUnknownImageSizeIconChanged; if (handler != null) this.UseUnknownImageSizeIconChanged(this, e); }
#endregion
#region IMultipleImageProvider Members
/// <summary> /// Queries the image provider for support of a specific size. /// </summary> /// <param name="key">Key used to identify an image.</param> /// <param name="size">Indicated image size</param> /// <returns>Returns true when the requested size is supported.</returns> public virtual bool IsImageSupported(object key, ImageSize size) { return ImageProvider.IsImageSupported(key, size); }
/// <summary> /// Fetches an image of the requested size. /// </summary> /// <param name="key">Key used to identify an image.</param> /// <param name="size">Size of image to obtain.</param> /// <returns>If supported, returns requested image. A value of null /// indicates that the requested size is not supported.</returns> public virtual Image GetImage(object key, ImageSize size) { return ImageProvider.GetImage(key, size); }
/// <summary> /// Gets count of registered image providers. /// </summary> public virtual int ImageProviderCount { get { return ImageProvider.Count; } }
#endregion
#region IImageProvider Members
/// <summary> /// Queries the image provider for support of a specific size. /// </summary> /// <param name="size">Indicated image size.</param> /// <returns>Returns true when the requested size is supported.</returns> public virtual bool IsImageSupported(ImageSize size) { if (DefaultImageProvider == null) return false; if (DefaultImageProvider == this) return true;
return DefaultImageProvider.IsImageSupported(size); }
/// <summary> /// Fetches an image of the requested size. /// </summary> /// <param name="size">Size of image to obtain.</param> /// <returns>If supported, returns requested image. A value of null /// indicates that the requested size is not supported.</returns> public virtual Image GetImage(ImageSize size) { if (DefaultImageProvider == null) throw new NullReferenceException();
if (DefaultImageProvider == this) { Size iconSize = IconImageProvider.GetIconSize(size); Icon iconResult = new Icon(Resources.stop, iconSize); return iconResult.ToBitmap(); }
return DefaultImageProvider.GetImage(size); }
#endregion
#region IPersistComponentSettings Members
public void LoadComponentSettings() { // Read settings from the settings provider. Settings.Reload(); ApplySettings(); }
public void ResetComponentSettings() { // Reset to the default image size. Settings.Reset(); ApplySettings(); }
public void SaveComponentSettings() { // Save settings to the settings provider. RetrieveSettings(); Settings.Save(); }
protected virtual void ApplySettings() { this.ImageSize = Settings.ImageSize; }
protected virtual void RetrieveSettings() { Settings.ImageSize = this.ImageSize; }
[DefaultValue(false)] public bool SaveSettings { get; set; }
string IPersistComponentSettings.SettingsKey { get { return this.Name; } set { throw new NotSupportedException(); } }
#endregion
#region ToolStrip Overrides
protected override void Dispose(bool disposing) { if (disposing) { try { SaveComponentSettings(); } finally { } }
base.Dispose(disposing); }
#endregion
#region Methods
/// <summary> /// Call to begin a batch image provider update more efficiently. /// Each 'BeginImageProviderUpdate' call <b>MUST</b> be paired with /// an 'EndImageProviderUpdate' call. /// </summary> public virtual void BeginUpdateImages() { IsUpdatingImages = true; }
/// <summary> /// Call to end a batch image provider update. Please note that any /// image refreshements only occur when all nested updates are ended. /// </summary> /// <param name="refresh">Indicates if image sizes are to be refreshed.</param> public virtual void EndUpdateImages(bool refresh) { if (!IsUpdatingImages) throw new NotSupportedException();
IsUpdatingImages = false;
// Only apply updates when image providers have been changed. if (HasImagesChanged) { HasImagesChanged = false;
// If no longer updating image providers (i.e. no nested calls), then // refresh the image sizes. if (!IsUpdatingImages && refresh) RefreshItemImages(); } }
/// <summary> /// Call to end a batch image provider update. Please note that /// image refreshements only occur when all nested updates are ended. /// </summary> public void EndUpdateImages() { EndUpdateImages(true); }
/// <summary> /// Assigns an image provider for the specified item. /// </summary> /// <param name="item">Associated toolstrip item.</param> /// <param name="provider">Image provider.</param> /// <returns>Returns true when successful.</returns> public bool AssignImage(ToolStripItem item, IImageProvider provider) { if (item == null || provider == null) throw new ArgumentException("One or more arguments were null references."); if (ContainsImage(item)) return false;
ImageProvider.Add(item, provider); HasImagesChanged = true;
if (!IsUpdatingImages) RefreshItemImages();
return true; }
/// <summary> /// Assigns an image provider for the specified item. /// </summary> /// <param name="item">Associated toolstrip item.</param> /// <param name="item">Associated multi-icon.</param> /// <returns>Returns true when successful.</returns> public bool AssignImage(ToolStripItem item, Icon icon) { return AssignImage(item, new IconImageProvider(icon)); }
/// <summary> /// Unregisters an image provider. /// </summary> /// <param name="item">Associated toolstrip item.</param> /// <returns>Returns true when successful.</returns> public bool RemoveImage(ToolStripItem item) { if (ImageProvider.Remove(item)) { HasImagesChanged = true;
if (!IsUpdatingImages) RefreshItemImages(); return true; } return false; }
/// <summary> /// Remove image providers which are not referenced with a <c>ToolStripItem</c>. /// </summary> /// <returns>Returns count of items removed.</returns> public int RemoveUnusedImages() { List<ToolStripItem> removeList = new List<ToolStripItem>(); int count = 0;
// Compile a list of all items which are to be removed. foreach (ToolStripItem key in ImageProvider.Keys) if (!Items.Contains(key as ToolStripItem)) removeList.Add(key); count = removeList.Count;
// Remove each item from provider collection. foreach (ToolStripItem item in removeList) RemoveImage(item);
// Make sure that the removal list is disposed of. removeList = null; return count; }
/// <summary> /// Searches for the a provider which is associated with a toolstrip item. /// </summary> /// <param name="item">Toolstrip item.</param> /// <returns>Returns true when an associated provider is found.</returns> public bool ContainsImage(ToolStripItem item) { return ImageProvider.ContainsKey(item); }
/// <summary> /// Forces all images sizes to be refreshed from the respective providers. /// </summary> protected void RefreshItemImages() { Size imageSize = IconImageProvider.GetIconSize(ImageSize); ImageScalingSize = imageSize;
bool changesMade = false; IImageProvider imageProvider = null; SuspendLayout();
foreach (ToolStripItem item in Items) { if (item.Size != imageSize) { imageProvider = null;
// If an image provider was registered with the toolstrip then... if (ContainsImage(item)) { if (IsImageSupported(item, ImageSize)) item.Image = GetImage(item, ImageSize); else if (UseUnknownImageSizeIcon && IsImageSupported(ImageSize)) item.Image = GetImage(ImageSize);
changesMade = true; } else if (item is IImageProvider) { imageProvider = item as IImageProvider; } else if (item.Tag is IImageProvider) { imageProvider = item.Tag as IImageProvider; }
// If an alternative image provider was found, attempt to use that. if (!changesMade && imageProvider != null) { if (imageProvider.IsImageSupported(ImageSize)) { item.Image = imageProvider.GetImage(ImageSize); changesMade = true; } }
// Were changes made? if (changesMade) { // Automatically adjust the image scaling mode. if (item.Image != null && item.Image.Size == imageSize) item.ImageScaling = ToolStripItemImageScaling.None; else item.ImageScaling = ToolStripItemImageScaling.SizeToFit; } } }
ResumeLayout(); }
#endregion
#region Properties
/// <summary> /// Gets or sets the default image provider. /// </summary> public IImageProvider DefaultImageProvider { get { return this.m_defaultProvider; } set { this.m_defaultProvider = value; } }
/// <summary> /// Gets the active multiple image provider. /// </summary> protected ImageProviderCollection ImageProvider { get { return this.m_imageProvider; } }
/// <summary> /// Gets or sets the active toolstrip item images sizes. /// </summary> public ImageSize ImageSize { get { return this.m_imageSize; } set { if (value != this.m_imageSize) { ImageSizeChangingEventArgs e = new ImageSizeChangingEventArgs(this.m_imageSize, value); if (OnImageSizeChanging(e)) { // Adjust image scaling mode. ImageScalingSize = IconImageProvider.GetIconSize(value);
// Adjust image size as specified. this.m_imageSize = value; RefreshItemImages(); OnImageSizeChanged(new OldNewEventArgs<ImageSize>(e.CurrentValue, value)); } } } }
/// <summary> /// Gets or sets whether a default icon is used to represent unsupported /// image sizes. /// </summary> public bool UseUnknownImageSizeIcon { get { return this.m_useUnknownIcon; } set { if (value != this.m_useUnknownIcon) { this.m_useUnknownIcon = value; OnUseUnknownImageSizeIconChanged(EventArgs.Empty); } } }
/// <summary> /// Gets a value indicating if image providers are being updated. /// </summary> public bool IsUpdatingImages { get { return this.m_updatingProviders >
|
|
|
|
 |
|
 |
Lea:
I have implemented the changes you have here and understand that you wouldn't want to mess up the control directly so I took a different approach based on the fact that all MultipleImageToolStrips (MITS) should be configurable for my application users.
I simply allow them to double click on the ToolStripPanel to lock and unlock positions. It basically loops through all MITS objects and toggles the Grip visibility. If they are double-clicking to lock, then I call ToolStripManager to stow the positions. Otherwise, if the application is closing and the MITS aren't locked, then I stow the positions.
Here's some of the code modified on top of your source:
private static List<MultipleImageToolStrip> all;
static MultipleImageToolStrip() { all = new List<MultipleImageToolStrip>(); }
public MultipleImageToolStrip() { this.m_imageProvider = new ImageProviderCollection(); this.m_defaultProvider = this; this.m_settings = new PersistentIconToolStripSettings((this as IPersistComponentSettings).SettingsKey); all.Add(this); }
...
public static void Lock() { foreach (MultipleImageToolStrip m in all) { m.GripStyle = ToolStripGripStyle.Hidden; } }
public static void Unlock() { foreach (MultipleImageToolStrip m in all) { m.GripStyle = ToolStripGripStyle.Visible; } }
I used this MultipleImageToolStrip.all to try to stow the ImageSize settings as well since your code seemed to take me half-way to a solution.
public static void SaveAllSettings() { foreach (MultipleImageToolStrip m in all) { m.SaveComponentSettings(); } }
public static void LoadAllSettings() { foreach (MultipleImageToolStrip m in all) { m.LoadComponentSettings(); } }
Then from my application's main form I have the following code.
private void Strips_TopToolStripPanel_DoubleClick(object sender, EventArgs e) { if (Strips.TopToolStripPanel.Locked) { Strips.TopToolStripPanel.Locked = false; Strips.LeftToolStripPanel.Locked = false; Strips.RightToolStripPanel.Locked = false; MultipleImageToolStrip.Unlock(); } else { Strips.TopToolStripPanel.Locked = true; Strips.LeftToolStripPanel.Locked = true; Strips.RightToolStripPanel.Locked = true;
MultipleImageToolStrip.Lock(); ToolStripManager.SaveSettings(this); MultipleImageToolStrip.SaveAllSettings(); } }
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (!Strips.TopToolStripPanel.Locked) { ToolStripManager.SaveSettings(this); MultipleImageToolStrip.SaveAllSettings(); } }
private void Form1_Load(object sender, EventArgs e) { ToolStripManager.LoadSettings(this); MultipleImageToolStrip.LoadAllSettings(); }
This solution does not work. I have looked for the user.config entries and cannot find them. I'm new to the ApplicationSettingsBase and am curious if I'm missing something, if the ToolStripManager is interfering with persistence you added to MultipleImageToolStrip or if I just haven't set up a user.config file (do I need to?). I assume based on an attribute that the persistence you added in your last post is at the user level rather than the application level.
Thank you again for your correspondence.
Best Regards, Guy..L
modified on Tuesday, August 4, 2009 11:32 PM
|
|
|
|
 |
 | ToolStrip flicker Guy..L | 13:03 2 Aug '09 |
|
 |
Thank you for your excellent post for multisized toolstrips.
I commonly change the icon associated with a toolstrip button because I want to indicate a change in status, a toggle condition, or indicate a kind of wizard step on the image.
I notice that when I use RemoveImage and then AssignImage, the length of the toolstrip changes by the width of the button between the two calls. In some cases, the image is changed every second.
Is there any way to change the icon without the toolstrip updating? Are these two calls the best way to change an icon image?
Thanks again.
Best Regards, Guy..L
|
|
|
|
 |
|
 |
Hi,
Thank you for your kind words.
I think I have managed to find the source of this problem. Have a go at replacing the "RefreshItemImages" method inside "MultipleImageToolStrip" with the following implementation. The version below suspends layout changes until all image changes have been made.
protected void RefreshItemImages() { Size imageSize = IconImageProvider.GetIconSize(ImageSize); ImageScalingSize = imageSize;
bool changesMade = false; IImageProvider imageProvider = null; SuspendLayout();
foreach (ToolStripItem item in Items) { if (item.Size != imageSize) { imageProvider = null;
if (ContainsImage(item)) { if (IsImageSupported(item, ImageSize)) item.Image = GetImage(item, ImageSize); else if (UseUnknownImageSizeIcon && IsImageSupported(ImageSize)) item.Image = GetImage(ImageSize);
changesMade = true; } else if (item is IImageProvider) { imageProvider = item as IImageProvider; } else if (item.Tag is IImageProvider) { imageProvider = item.Tag as IImageProvider; }
if (!changesMade && imageProvider != null) { if (imageProvider.IsImageSupported(ImageSize)) { item.Image = imageProvider.GetImage(ImageSize); changesMade = true; } }
if (changesMade) { if (item.Image != null && item.Image.Size == imageSize) item.ImageScaling = ToolStripItemImageScaling.None; else item.ImageScaling = ToolStripItemImageScaling.SizeToFit; } } }
ResumeLayout(); } Give this a try and let me know how you get on. If this fixes your problem I will submit an update for this article.
Thanks for reporting this problem!
Lea Hayes
|
|
|
|
 |
|
 |
That does it. Thanks again.
|
|
|
|
 |
 | Thank You iccb1013 | 20:56 25 Jul '09 |
|
|
 |
 | Icon 16x16 32 x 32 Cliffer | 5:45 26 Feb '09 |
|
 |
hi all... I have a problem with my toolstrip and my icons. My icons are in 16x16 & 32x32 format. If I set ImageScalingSize to 32,32 all work ok, but if I set the property to 16, 16 values my toolstrip button resize but the icon shown was not my 16x16 icon but 32x32 auto resized by system...
someone can help me?? thanks in advance. Cliffer
|
|
|
|
 |
|
 |
Hi,
The simplest approach is to create an icon resource which contains your 16x16 and 32x32 images (.ico file). It is also a good idea to include a range of colour depths.
Then to incorporate into the tool strip, use something like the following:
private void Form1_Load(object sender, EventArgs e) { this.iconToolStrip.BeginUpdateImages();
this.iconToolStrip.AssignImage(toolStripForward, Resources.arrow_right);
this.iconToolStrip.EndUpdateImages();
this.iconToolStrip.ImageSize = ImageSize.Large; }
If you need any further assistance, feel free to ask.
Thanks! Lea Hayes
|
|
|
|
 |
 | insert gripper into toolstrip 1016 | 4:02 19 Nov '08 |
|
 |
Hi, Nice article. I want to ask a question that how to insert a gripper into toolstrip so that it could be moved via mouse in order to resize the control left side of the gripper and moving the contorls right side of the gripper. For example you can consult google toolbar. There is a gripper on left of search combobox through which this combobox can be resizzed. Can you tell me how to implement this. Bundle of Thanks in advance. Cheers Rizwan
|
|
|
|
 |
|
|