WinForms DataGridView не отвечает при отображении изображений - PullRequest
0 голосов
/ 22 марта 2020

У меня есть приложение, которое позволяет пользователям загружать выбранные изображения в DataGridView и выполнять операции над ними. Однако, когда выбрано несколько изображений, форма останавливается до тех пор, пока информация об изображении не будет загружена в DataGridView. Я пробовал BackgroundWorker для этого, но он тоже не работает. Мои коды выглядят так:

private void button1_Click(object sender, EventArgs e)
{
    var file = new OpenFileDialog
    {
        Filter = @"TIFF |*.tiff| TIF|*.tif",
        FilterIndex = 1,
        Title = @"Select TIFF file(s)...",
        Multiselect = true
    };
    if (file.ShowDialog() == DialogResult.OK)
    {
        Listing(file.FileNames);
    }
}
private void Listing(string[] files)
{
    foreach (var file in files)
    {
        var pic_name = Path.GetFileName(file);

        if (file != null)
        {
            // Image from file
            var img = Image.FromFile(file);
            // Get sizes of TIFF image
            var pic_sizes = img.Width + " x " + img.Height;
            // Get size of TIFF image
            var pic_size = new FileInfo(file).Length;
            //Create the new row first and get the index of the new row
            var rowIndex = dataGridView1.Rows.Add();
            //Obtain a reference to the newly created DataGridViewRow 
            var row = dataGridView1.Rows[rowIndex];
            //Now this won't fail since the row and columns exist 
            row.Cells["name"].Value = pic_name;
            row.Cells["sizes"].Value = pic_sizes + " pixels";
            row.Cells["size"].Value = pic_size + " bytes";
        }
    }
}

Как я могу решить эту проблему?

РЕДАКТИРОВАТЬ: После комментария Алекса я попробовал так:

private void button1_Click(object sender, EventArgs e)
{
    var file = new OpenFileDialog
    {
        Filter = @"TIFF |*.tiff| TIF|*.tif",
        FilterIndex = 1,
        Title = @"Select TIFF file(s)...",
        Multiselect = true
    };
    if (file.ShowDialog() == DialogResult.OK)
    {
        _ = Test(file.FileNames);
    }
}
private async Task Test(string[] s)
{
    await Task.Run(() => Listing(s));
}
private void Listing(string[] files)
{
    BeginInvoke((MethodInvoker) delegate
    {
        foreach (var file in files)
        {
            var pic_name = Path.GetFileName(file);

            if (file != null)
            {
                // Image from file
                var img = Image.FromFile(file);
                // Get sizes of TIFF image
                var pic_sizes = img.Width + " x " + img.Height;
                // Get size of TIFF image
                var pic_size = new FileInfo(file).Length;
                //Create the new row first and get the index of the new row
                var rowIndex = dataGridView1.Rows.Add();
                //Obtain a reference to the newly created DataGridViewRow 
                var row = dataGridView1.Rows[rowIndex];
                //Now this won't fail since the row and columns exist 
                row.Cells["name"].Value = pic_name;
                row.Cells["sizes"].Value = pic_sizes + " pixels";
                row.Cells["size"].Value = pic_size + " bytes";
            }
        }
    });
}

Но, к сожалению, результат тот же.

1 Ответ

1 голос
/ 22 марта 2020

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

private readonly BindingList<Tiff> _tiffs = new BindingList<Tiff>();
private void button1_Click(object sender, EventArgs e)
{
    Listing();
}
private void Listing()
{
    foreach (var f in _tiffs)
    {
        if (f != null)
        {
            var rowIndex = dataGridView1.Rows.Add();
            //Obtain a reference to the newly created DataGridViewRow 
            var row = dataGridView1.Rows[rowIndex];
            //Now this won't fail since the row and columns exist 
            row.Cells["ColName"].Value = f.ColName;
            row.Cells["ColSizes"].Value = f.ColSizes + " pixels";
            row.Cells["ColSize"].Value = f.ColSize + " bytes";
        }
    }
}
public static List<string> Files(string dir, string ext = "*.tiff")
{
    var DirInfo = new DirectoryInfo(dir);
    return DirInfo.EnumerateFiles(ext, SearchOption.TopDirectoryOnly).Select(x => x.FullName).ToList();
}
public void SetSource()
{
    // Source folder of images...
    var files = Files(@"___SOURCE_DIR___");
    var total = files.Count;
    var i = 1;
    foreach (var file in files)
    {
        var pic_name = Path.GetFileName(file);
        var img = Image.FromFile(file);
        // Get sizes of TIFF image
        var pic_sizes = img.Width + " x " + img.Height;
        // Get size of TIFF image
        var pic_size = new FileInfo(file).Length.ToString();
        _tiffs.Add(new Tiff(pic_name, pic_sizes, pic_size));
        BeginInvoke((MethodInvoker)delegate
        {
            label1.Text = $@"{i} of {total} is added to the BindingList.";
        });
        i++;
    }
}
private void button2_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    SetSource();
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // Set something if you want.
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Set something if you want.
}
public class Tiff
{
    public Tiff(string name, string sizes, string size)
    {
        ColName = name;
        ColSizes = sizes;
        ColSize = size;
    }
    public string ColName { get; set; }
    public string ColSizes { get; set; }
    public string ColSize { get; set; }
}

И вот результат: enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...