我有一个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 :(得分:0)
问题是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);
......它运作正常。
答案 1 :(得分:0)
每次从ImageList中删除图像时,您都必须递减每个ListViewItem的ImageIndex,该ImageIndex指向的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();