我正在使用带有ImageList的TreeView。由于TreeView中填充了项目,因此每个项目都会有一个与之关联的图标。其中许多图标可能完全相同,但目前我没有添加任何代码来跟踪重复项,我只需将每个图标添加到ImageList,然后跟踪与每个TreeNode关联的图标。
我的问题是.Net如何处理这些资源。例如,运行时是否意识到某些图标完全相同,因此只为所有重复项加载相同的图标一次?如果没有,如果这样做了数万次,我是否会遇到资源问题(这不是典型的,但可能会发生)?
答案 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);
}
}