Как исправить ListView.LargeImageList, показывающий изображения дважды - PullRequest
1 голос
/ 08 мая 2019

Я работаю над программным обеспечением, которое сравнивает мемы и помогает пользователям организовывать мемы на своем компьютере. Как часть этого я использую Windows.Forms для создания пользовательского интерфейса. Этот интерфейс позволяет пользователю добавлять папки для проверки изображений, которые можно сравнить с набором известных шаблонов мемов. Моя проблема возникает, когда я пытаюсь показать пользователю найденные изображения. Для этого я использую ListView и свойство LargeImageList для хранения кортежа изображения и имени файла изображения.

Вот фрагмент кода, о котором идет речь:

private void button1_Click(object sender, EventArgs e)
{
    int i = 0;
    var ic = new ImageCollection();
    var fbd = new FolderBrowserDialog();
    fbd.Description = "Select meme folder or image.";
    if (fbd.ShowDialog() == DialogResult.OK)
    {
        string[] files = Directory.GetFiles(fbd.SelectedPath);
        foreach (var file in files)
        {
            if (!ic.CheckIfImage(file)) continue;
            imageList1.Images.Add(Image.FromFile(file));

        }

        foreach (var file in files)
        {
            listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++);
        }
    }
}

Этот является примером того, что видит пользователь при первой загрузке в папку. Когда пользователь пытается загрузить в другую папку , это происходит. Показывает изображения из первой папки с именами файлов изображений из второй папки.

Кто-нибудь знает решение этой проблемы? Я пробовал множество вариантов, чтобы обойти эту проблему. Все от попыток очистить ImageList, используемых для хранения изображений, до попытки контролировать, когда обновляется ListView. Ничего из этого не сработало. Я также попытался найти проблему, но безуспешно, чтобы найти решение.

Заранее спасибо.

1 Ответ

1 голос
/ 08 мая 2019

Если вы хотите отобразить содержимое одной папки за раз, тогда утилизируйте объекты в вашем ImageList.

Если вы хотите показать содержимое более чем одной папки, вам нужно указать новый индекс добавленного изображения. Вместо этого вы добавляете новый элемент в ListView, используя ту же ссылку индекса:

int i = 0;
//(...)
listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++); 

Индексатор (i) всегда начинается с 0, поэтому элемент ListView будет использовать изображения из вашего списка изображений, начиная с изображения с Index[0] каждый раз. Новые изображения никогда не будут показаны.

Вы можете использовать значение ImageList.Images.Count, представляющее количество изображений, уже добавленных в ImageList, в качестве базы и увеличивать индексатор, начиная с этого значения:

private void button1_Click(object sender, EventArgs e)
{
    int i = imageList1.Images.Count;
    var ic = new ImageCollection();
    var fbd = new FolderBrowserDialog();
    fbd.Description = "Select meme folder or image.";
    if (fbd.ShowDialog() == DialogResult.OK)
    {
        foreach (var file in Directory.GetFiles(fbd.SelectedPath))
        {
            if (!ic.CheckIfImage(file)) continue;
            imageList1.Images.Add(new Bitmap(file, true));
            listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++);
        }
    }
}

Если вы разрешаете удалить изображение из ListView, вы также должны удалить его из ImageList: это означает, что вам необходимо переиндексировать все элементы ListView, начиная с элемента, следующего за удаленным.
Не забудьте утилизировать изображения, которые вы удаляете из списка изображений.

...