Thank you very much Govert, there are a few issues where the wrong images are shown after making your changes because the names array wasn't updated to remove the null images. The code below fixes them:
private string[] names;
private ListViewItem[] listViewItems;
....
public Gallery()
{
...
Icons.BeginUpdate();
var smallImageList = new List<Bitmap>();
var largeImageList = new List<Bitmap>();
var namesList = new List<string>();
var listViewItemList = new List<ListViewItem>();
foreach (var name in imageMso.Names)
{
var smallImage = imageMso[name, 16, 16];
var largeImage = imageMso[name, 32, 32];
if (smallImage != null && largeImage != null)
{
namesList.Add(name);
smallImageList.Add(smallImage);
largeImageList.Add(largeImage);
listViewItemList.Add(new ListViewItem(name, namesList.Count - 1));
}
}
names = namesList.ToArray();
listViewItems = listViewItemList.ToArray();
Icons.SmallImageList.Images.AddRange(smallImageList.ToArray());
Icons.LargeImageList.Images.AddRange(largeImageList.ToArray());
Icons.Items.AddRange(listViewItems);
Icons.EndUpdate();
...
}
private void SetFilters_LostFocus(object sender, EventArgs e)
{
SetFilters.Text = SetFilters.Text.Trim();
if (!SetFilters.AutoCompleteCustomSource.Contains(SetFilters.Text))
SetFilters.AutoCompleteCustomSource.Add(SetFilters.Text);
if (SetFilters.Text != pattern)
{
pattern = SetFilters.Text;
Clear.Enabled = SetFilters.Text.Length > 0;
Filter.Checked = SetFilters.Text.Length > 0;
// Comma separated array of keyword groups which are in turn space separated arrays of keywords.
var filter = Array.ConvertAll(pattern.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries),
search => search.Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
Icons.BeginUpdate();
Icons.Items.Clear();
// Find all names where there exists a keyword group in the filter such that the name contains
// all the keywords in the group, convert all names found to listview items and add as a range.
if (filter.Length > 0) Icons.Items.AddRange(Array.ConvertAll(Array.FindAll(names,
name => Array.Exists(filter, group => Array.TrueForAll(group,
keyword => name.ToLowerInvariant().Contains(keyword.ToLowerInvariant().Trim())))),
name => new ListViewItem(name, Array.IndexOf(names, name))));
else Icons.Items.AddRange(listViewItems);
if (Icons.Items.Count > 0) Icons.FocusedItem = Icons.Items[0];
Icons.EndUpdate();