[英]Winforms insert image into ListView / ImageList at index
Winforms, C#, VS2017 Winforms,C#,VS2017
ImageList does not have an Insert method (however ListViewItemCollection does). ImageList没有Insert方法(但是ListViewItemCollection有)。 I have tried a few different ways to insert a new image into the middle of a ListView and it's LargeImageList, but not getting it to work quite properly.
我尝试了几种不同的方法将新图像插入到ListView的中间,它是LargeImageList,但没有使其正常工作。
Anyone have any tried and true code that works properly? 任何人都有经过实践检验的正确代码吗?
This is what I have, but the images don't get synced properly to the items in the list. 这就是我所拥有的,但是图像无法正确同步到列表中的项目。
protected void InsertThumbnail(string key, string keySelected)
{
var newImageList = new ImageList()
{
ImageSize = new Size(thumbWidth, thumbHeight)
};
var itemNew = new ListViewItem();
var foundSelected = false;
//lvAllPages.BeginUpdate();
for (int i = 0; i < lvAllPages.Items.Count; i++)
{
var item = lvAllPages.Items[i];
newImageList.Images.Add(item.Tag.ToString(), lvAllPages.LargeImageList.Images[i]);
if (item.Tag.ToString() == keySelected)
{
var image = batch.GetThumbnail(key);
newImageList.Images.Add(key, image);
itemNew = new ListViewItem()
{
BackColor = Color.Aquamarine,
ImageIndex = i,
Tag = key,
};
if (isLocal)
itemNew.Text = $"{GetFileName(key)} (insert) - {itemNew.ImageIndex}";
foundSelected = true;
}
if (foundSelected)
{
item.ImageIndex = item.ImageIndex + 1;
if (isLocal)
item.Text = $"{GetFileName(item.Tag.ToString())} - {item.ImageIndex}";
}
}
lvAllPages.LargeImageList.Dispose();
lvAllPages.LargeImageList = newImageList;
lvAllPages.Items.Insert(itemNew.ImageIndex, itemNew);
}
One more related thing, but not pertinent to the problems I am having. 还有另一件事,但与我遇到的问题无关。 For anyone looking at this question and having similar issues, this helped with the issue of sorting items after inserting a new one.
对于任何关注此问题并有类似问题的人,这有助于解决在插入新项目后对项目进行排序的问题。 Default behavior when you insert a new ListViewItem at a given index, it will appear at the bottom of the list.
当您在给定的索引处插入新的ListViewItem时的默认行为,它将出现在列表的底部。 I found this handy class to keep items sorted by index, which solved that problem:
我发现这个方便的类可以使项目按索引排序,从而解决了该问题:
class CompareByIndex : IComparer { private readonly ListView _listView; class CompareByIndex:IComparer {私有只读ListView _listView;
public CompareByIndex(ListView listView)
{
this._listView = listView;
}
public int Compare(object x, object y)
{
int i = this._listView.Items.IndexOf((ListViewItem)x);
int j = this._listView.Items.IndexOf((ListViewItem)y);
return i - j;
}
} }
And in the form load: 并在形式加载中:
lvAllPages.ListViewItemSorter = new CompareByIndex(lvAllPages); lvAllPages.ListViewItemSorter =新的CompareByIndex(lvAllPages);
Obviously, that's a design decision. 显然,这是设计决定。
ImageList.Images
is a ImageCollection
and as such, it implements the IList
interface. ImageList.Images
是一个ImageCollection
,因此,它实现了IList
接口。
Unfortunately, the Insert()
method is allowed to throw a NotSupportedException
. 不幸的是,允许
Insert()
方法抛出NotSupportedException
。 And that's what the list will do when used like a IList
: 这就是像
IList
一样使用时列表将要做的事情:
((IList)imageList.Images).Insert(5, new Bitmap(10,10));
System.NotSupportedException: 'Specified method is not supported.'
System.NotSupportedException:'不支持指定的方法。
In order to have the images shown in a specific order, use the Add()
method which takes the key: 为了使图像以特定顺序显示,请使用采用以下键的
Add()
方法:
imageList.Images.Add("1", new Bitmap(100,100));
That should also enable you to replace the image: 那也应该使您能够替换图像:
imageList.Images.RemoveByKey("1");
imageList.Images.Add("1", new Bitmap(200,200));
For that to work, you need to set the Sorting property: 为此,您需要设置Sorting属性:
listView1.Sorting = SortOrder.Ascending;
For storing additional information like path etc. use anotther data structure with the same key. 为了存储路径等其他信息,请使用具有相同密钥的其他数据结构。
Here's the code: 这是代码:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
ImageList imageList = new ImageList();
Dictionary<string, Metadata> metadata = new Dictionary<string, Metadata>();
private string dir = @"H:\temp";
private void button1_Click(object sender, EventArgs e)
{
// You would set this in the designer, probably
listView1.Sorting = SortOrder.Ascending;
listView1.View = View.LargeIcon;
listView1.LargeImageList = imageList;
// Make sure we start from the beginning
listView1.Items.Clear();
imageList.Images.Clear();
metadata.Clear();
// Add items
for (int i = 0; i < 10; i++)
{
var filename = "1 ("+(i+1)+").png"; // Just strange names I have
var fullFileName = Path.Combine(dir, filename);
imageList.Images.Add(i.ToString(), Bitmap.FromFile(fullFileName));
metadata.Add(i.ToString(), new Metadata{Path = fullFileName});
listView1.Items.Add(i.ToString(), "Image " + i, i.ToString());
}
// Update view
listView1.Refresh();
listView1.Invalidate();
}
private void button2_Click(object sender, EventArgs e)
{
for (int i = 3; i < 6; i++)
{
var filename = "1 ("+(i+2)+").png";
var fullFileName = Path.Combine(dir, filename);
// Change image
imageList.Images.RemoveByKey(i.ToString());
imageList.Images.Add(i.ToString(), Bitmap.FromFile(fullFileName));
// Match metadata and image
metadata[i.ToString()] = new Metadata{Path = fullFileName};
}
listView1.Refresh();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.SelectedItems.Count > 0)
{
var key = listView1.SelectedItems[0].ImageKey;
label1.Text = metadata[key].Path;
}
else
{
label1.Text = "No image selected";
}
}
}
internal class Metadata
{
internal string Path;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.