【问题标题】:Strange behavior while removing image from ListView从 ListView 中删除图像时出现奇怪的行为
【发布时间】:2012-03-11 19:33:57
【问题描述】:

我有一个 ListView,我用 ImageList 的内容填充它。当从列表中选择一个项目时,我检查该文件是否仍然存在。如果没有,我想将它从图像列表(私有静态)和 ListView 中删除。 出于某种奇怪的原因,我无法弄清楚,从列表中删除选定的图像后,图像立即消失,列表中的最后一个图像出现两次。 例如,如果列表包含以下图像:IMG1、IMG2、IMG3、IMG4、IMG5 并且我删除了 IMG2,新列表将如下所示:IMG1 , IMG4, IMG5, IMG5.

此外,如果我从列表中选择第二张图片(现在是 IMG4)并将其显示在某个图片控件 IMG3 中,该控件应该在该地点将显示在控件中。

有什么想法吗?

编辑: 填充列表视图:

private static ImageList stampsImages

        if (stampsImages == null)
        {
            stampsImages = new ImageList();
            stampsImages.ImageSize = new Size(125, 75);
        }

        DirectoryInfo di = new DirectoryInfo(Globals.Directory);
        if (di.Exists)
        {
            FileInfo[] dFiles = di.GetFiles("*.png");
            int stampListSize = stampsImages.Images.Count;

            for (int i = 0; i < dFiles.Length; i++)
            {
                int idx = stampsImages.Images.IndexOfKey(dFiles[i].FullName);

                if (idx < 0)
                {
                    stampsImages.Images.Add(Bitmap.FromFile(dFiles[i].FullName));
                    stampsImages.Images[stampListSize].Tag = dFiles[i].FullName; 
                    stampsImages.Images.SetKeyName(stampListSize, dFiles[i].FullName);
                    stampListSize++;
                }
            }
        }
        else di.Create();

        for (int i = 0; i < stampsImages.Images.Count; i++)
        {
            ListViewItem stmp = new ListViewItem("", i);
            lvwStamps.Items.Add(stmp);
        }
        lvwStamps.LargeImageList = stampsImages;      

检查文件是否仍然存在:

    private bool IsStampAvailable(int listIdx)
    {
        bool stampExists = true;
        string stampFile = stampsImages.Images.Keys[listIdx];
        if (!File.Exists(stampFile))
        {
            lvwStamps.Items.RemoveAt(listIdx);
            stampsImages.Images.RemoveAt(listIdx);
            stampExists = false;
        }

        return stampExists;
    }

【问题讨论】:

  • 一些代码可能比描述您认为正在发生的事情更有用。你只会描述你期望你的代码在做什么,而不是它实际上在做什么,如果它在做你期望的事情,你就不会在这里......
  • 这听起来像是基于 0 与基于 1 的索引问题。
  • 至少向我们展示删除代码。
  • 这是一个 WinForms 项目。

标签: c# winforms image listview


【解决方案1】:

问题在于 ListView 项可能会记住 ImageList 中图像的索引。如果从 ImageList 中删除图像,ListView 项将指向错误的图像。

尝试通过键而不是索引来引用图像。


这是我做的测试

imageList1.Images.Add("img0", Properties.Resources.img0); // Use key as first argument.
imageList1.Images.Add("img1", Properties.Resources.img1);
imageList1.Images.Add("img2", Properties.Resources.img2);
imageList1.Images.Add("img3", Properties.Resources.img3);
imageList1.Images.Add("img4", Properties.Resources.img4);
imageList1.Images.Add("img5", Properties.Resources.img5);
for (int i = 0; i < 6; i++) {
    var item = new ListViewItem(
        "Image #" + i, // Text
        "img" + i      // <== Use key here, not index
    );
    listView1.Items.Add(item);
}

如果我删除带有...的条目

listView1.Items[1].Remove();
imageList1.Images.RemoveAt(1);

...它工作正常。

【讨论】:

  • 出于某种原因,它似乎对我不起作用。当我使用键而不是索引时,我在 Listview 中看不到图像。
  • 您确定提供给ListViewItem.Add(caption, key); 和图像imageList1.Images.Add(key, image); 的密钥相同吗?这是Image.Add 的第一个参数,但ListViewItem.Add 的第二个参数。
  • 是的,我确定。我又试了一次,还是不显示图片。
【解决方案2】:

每次从 ImageList 中删除图像时,您都必须减少每个 ListViewItem 的 ImageIndex,这些 ListViewItem 指向的 ImageIndex 等于或高于已删除图像的 ImageIndex。通常,在删除 Item 后,从 Item 的索引开始线性递减就足够了(如果 ImageList 和 ListViewItems 保持 1:1 的关系):

for (int i = lvItem.Index + 1; i < listView1.Items.Count; i++)
    listView1.Items[i].ImageIndex--;

也许更重要的是在重新索引后删除项目(删除 ListViewItem 后,ListView 必须重新绘制,并且索引应该按正确的顺序排列):

int iImageIndex = lvItem.ImageIndex;
int iIndex = lvItem.Index; 
for (int i = iIndex + 1; i < listView1.Items.Count; i++) // correct the image indicies
    listView1.Items[i].ImageIndex--;       
lvItem.Remove(); // repaint
Image img = ImageList1.Images[iImageIndex];
ImageList1.Images.RemoveAt(iImageIndex);
img.Dispose();

【讨论】:

    猜你喜欢
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    相关资源
    最近更新 更多