C# 处理大量重复图标的资源
我正在使用带有图像列表的树状视图。由于树视图中充满了项目,因此每个项目都有一个与其关联的图标。其中许多图标可能是相同的,但目前,我没有添加任何代码来跟踪重复项,我只是将每个图标添加到ImageList中,然后跟踪与每个树节点关联的图标C# 处理大量重复图标的资源,c#,.net,winforms,C#,.net,Winforms,我正在使用带有图像列表的树状视图。由于树视图中充满了项目,因此每个项目都有一个与其关联的图标。其中许多图标可能是相同的,但目前,我没有添加任何代码来跟踪重复项,我只是将每个图标添加到ImageList中,然后跟踪与每个树节点关联的图标 我的问题是关于.Net如何处理这些资源。例如,运行时是否意识到某些图标完全相同,因此对所有重复的图标只加载一次相同的图标?如果不是,如果这样做了数万次,我是否会遇到资源问题(这不是典型情况,但可能会发生)?框架没有任何机制来处理这样的资源,以确保不会加载重复项。在
我的问题是关于.Net如何处理这些资源。例如,运行时是否意识到某些图标完全相同,因此对所有重复的图标只加载一次相同的图标?如果不是,如果这样做了数万次,我是否会遇到资源问题(这不是典型情况,但可能会发生)?框架没有任何机制来处理这样的资源,以确保不会加载重复项。在树视图的情况下尤其如此,因为它使用的ImageList将这些图像作为包含树视图的表单的本地资源进行维护 我过去使用的一种方法是创建一个封装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;
}
}
}
嗨,斯科特,我要么不明白你的答案,要么你回答了另一个问题。我关心的不是ImageList的多个实例,而是分配给ImageList中多个插槽的同一图像的多个副本。例如,可以将相同的图像分配给插槽0、1、2、5和100。听起来好像您担心在多个TreeView(或其他控件)中有重复的图像,而不是在单个TreeView.ImageList中有重复的图像。在这两种情况下,.NET Framework都没有提供任何机制来管理这些资源和反常的重复。在注释中的示例中,您将有5个不同的图像副本,分别位于ImageList中的每个位置。您需要做的是自己跟踪副本,如果您检测到正在添加一个具有已存在图像的节点,请使用现有图像索引(或键)。感谢您的澄清。这几乎是我的假设,所以我已经在寻找替代策略。
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);
}
}