处理大量重复图标的资源

时间:2009-08-12 17:24:21

标签: c# .net winforms

我正在使用带有ImageList的TreeView。由于TreeView中填充了项目,因此每个项目都会有一个与之关联的图标。其中许多图标可能完全相同,但目前我没有添加任何代码来跟踪重复项,我只需将每个图标添加到ImageList,然后跟踪与每个TreeNode关联的图标。

我的问题是.Net如何处理这些资源。例如,运行时是否意识到某些图标完全相同,因此只为所有重复项加载相同的图标一次?如果没有,如果这样做了数万次,我是否会遇到资源问题(这不是典型的,但可能会发生)?

1 个答案:

答案 0 :(得分:2)

框架没有任何机制来处理这样的资源,只要确保您不会最终加载重复项。在TreeView的情况下尤其如此,因为它使用的ImageList将这些图像保存为包含TreeView的表单的本地资源。

我过去使用的方法是创建一个包装ImageList的单例对象。这允许您控制图像何时/如何添加到ImageList。

public sealed class ImageListManager
{
    private static volatile ImageListManager instance;
    private static object syncRoot = new object();
    private ImageList imageList;

    private ImageListManager()
    {
        this.imageList = new ImageList();
        this.imageList.ColorDepth = ColorDepth.Depth32Bit;
        this.imageList.TransparentColor = Color.Magenta;
    }

    /// <summary>
    /// Gets the <see cref="System.Windows.Forms.ImageList"/>.
    /// </summary>
    public ImageList ImageList
    {
        get
        {
            return this.imageList;
        }
    }

     /// <summary>
     /// Adds an image with the specified key to the end of the collection if it 
     /// doesn't already exist.
     /// </summary>
     public void AddImage(string imageKey, Image image)
     {
        if (!this.imageList.ContainsKey(imageKey))
        {
           this.imageList.Add(imageKey, image);
        }
     }

    /// <summary>
    /// Gets the current instance of the 
    /// <see cref="ImageListManager"/>.
    /// </summary>
    public static ImageListManager Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new ImageListManager();
                    }
                }
            }
            return instance;
        }
    }
}

然后,为TreeView提供对该ImageList的引用,通常在调用InitializeComponent()之后在表单构造函数中完成。

public partial class Form1 : Form
{
   public Form1()
   {
      InitializeComponent();
      this.treeView1.ImageList = ImageListManager.Instance.ImageList;
   }

   // Making some guesses about how you are adding nodes
   // and getting the associated image.
   public void AddNewTreeNode(string text, string imageKey, Image image)
   {
      TreeNode node = new TreeNode("display text");
      node.Name = "uniqueName";

      // This tells the new node to use the image in the TreeView.ImageList
      // that has imageKey as its key.
      node.ImageKey = imageKey;
      node.SelectedImageKey = imageKey;

      this.treeView1.Nodes.Add(node);

      // If the image doesn't already exist, this will add it.
      ImageListManager.Instance.AddImage(imageKey, image);
   }

}