搜索照片和进度条显示 [英] Search photos and progressbar display

查看:83
本文介绍了搜索照片和进度条显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有搜索按钮和进度栏的表单,用于在网络目录上查找照片. 它返回错误:

I have one form with a search button and a progress bar to find photos on a network dir. It returns a error:

System.Reflection.TargetInvocationException
  HResult=0x80131604
  Message=O destino de uma invocação accionou uma excepção.
  Source=mscorlib
  StackTrace:
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
   at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
   at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at _myprogram.Program.Main() in C:\Users\folder\Desktop\folder\folder\V10\folder\Program.cs:line 19
Inner Exception 1:
ArgumentOutOfRangeException: O índice estava fora do intervalo. Tem de ser não negativo e inferior ao tamanho da colecção.
Nome do parâmetro: índex

这是代码:

   public partial class FormProcuraFotos : Form
{
    public FormProcuraFotos()
    {
        InitializeComponent();
    }
    // We create the DataTable here so we can create the new inside the Worker_DoWork and use it also on the Worker_RunWorkerCompleted
    DataTable tableWithPhotos;
    private void button1_Click(object sender, EventArgs e)
    {
        // Make the progressBar1 to look like its allways loading something
        progressBar1.Style = ProgressBarStyle.Marquee;
        // Make it here visible
        progressBar1.Visible = true;
        var worker = new BackgroundWorker();

        // Event that runs on background
        worker.DoWork += this.Worker_DoWork;

        // Event that will run after the background event as finnished
        worker.RunWorkerCompleted += this.Worker_RunWorkerCompleted;
        worker.RunWorkerAsync();
    }

    // The reason for having this here was to work with the progress bar and to search for the photos and it will not block the UI Thread
    // My advice is to have them here and pass them to the next form with a constructor
    private void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        // We must create a list for all the files that the search it will find
        List<string> filesList = new List<string>();
        // Create the new DataTable to be used
        tableWithPhotos = new DataTable();
        tableWithPhotos.Columns.Add("Nome e formato do ficheiro (duplo clique para visualizar a imagem)");
        tableWithPhotos.Columns.Add("Caminho ( pode ser copiado Ctrl+C )");

        // What folders that we want to search for the files
        var diretorios = new List<string>() { @"‪C:\Users\folder\Pictures" };

        // What extensions that we want to search
        var extensoes = new List<string>() { ".jpg", ".bmp", ".png", ".tiff", ".gif" };

        // This 2 foreach are to search for the files with the extension that is on the extensoes and on all directories that are on diretorios
        // In for foreach we go through all the extensions that we want to search
        foreach (string entryExtensions in extensoes)
        {
            // Now we must go through all the directories to search for the extension that is on the entryExtensions
            foreach (string entryDirectory in diretorios)
            {
                // SearchOption.AllDirectories search the directory and sub directorys if necessary
                // SearchOption.TopDirectoryOnly search only the directory
                filesList.AddRange(Directory.GetFiles(entryDirectory, entryExtensions, SearchOption.AllDirectories));
            }
        }

        // And now here we will add all the files that it has found into the DataTable
        foreach (string entryFiles in filesList)
        {
            DataRow row = tableWithPhotos.NewRow();
            row[0] = Path.GetFileName(entryFiles);
            row[1] = entryFiles;
            tableWithPhotos.Rows.Add(row);
        }
    }
    private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // With the new constructor on the FormResultadosFotos, we pass the table like this so the form can receive it
        progressBar1.Visible = false;
        var NovoForm = new FormResultadosFotos(tableWithPhotos);
        NovoForm.Show();
    }
}

} 我还有另一种形式可以在datagridview上显示这些结果(该datagridview有一个图片框,如果用户双击该图片框将显示照片) 这是代码:

} I have another form to display those results on a datagridview (this datagridview has a picturebox that shows the photo if a user double click) Here is the code:

public partial class FormResultadosFotos : Form
{
    // This is the constructor that we have added to the FormResultadosFotos so it can receive the DataTable that was created on the previous form
    public FormResultadosFotos(DataTable table)
    {
        InitializeComponent();
        dataGridView1.DataSource = table;
        dataGridView1.Columns[1].Visible = true;
        // What can be done here to not block the UI thread if is being blocked while populating the dataGridView1, is to create another BackgroundWorker here and populate the dataGridView1 there
    }
}

}

是否可以帮助我并指出问题所在?谢谢.

Is it possible to help me and show what is wrong? Thank you.

推荐答案

我将把ProgressBar更改为像这样progressBar1.Style = ProgressBarStyle.Marquee;继续,并且因为它在那里没有在Worker_DoWork上使用它,但是却没有做任何事情. 我建议的代码是这样的,BackgroundWorker正在执行其工作,搜索文件且未阻止UI线程AKA在执行可能需要很长时间的任务时未阻止程序 单击后,我们可以将其显示为可见,然后在完成工作后,将Worker_RunWorkerCompleted变为不可见.

I would change the ProgressBar to be continue like this progressBar1.Style = ProgressBarStyle.Marquee; and don't have it on the Worker_DoWork since its there but doing nothing in some sorts. The code that I advice is like this, the BackgroundWorker is doing its job, searching for the files and not blocking the UI Thread AKA not blocking the program while doing a task that can take a long time On the click we can make it visable and then o the Worker_RunWorkerCompleted invisible after the work as been done.

我确实在这里更改了Worker_DoWork,删除了progressBar1上的更新,因为该更新仅用于外观而不做其他任何事情,并使它完成其工作,该过程可能需要很长时间,这就是它们的用途.

I did change the Worker_DoWork here, remove the update on the progressBar1 since it was there just for the looks and doing nothing else and make it do its job, a process that can take a long time, that is what they are for

public partial class FormPesquisaFotos : Form
{
    // We create the DataTable here so we can create the new inside the Worker_DoWork and use it also on the Worker_RunWorkerCompleted
    DataTable tableWithPhotos;
    private void button1_Click(object sender, EventArgs e)
    {
        // Make the progressBar1 to look like its allways loading something
        progressBar1.Style = ProgressBarStyle.Marquee;
        // Make it here visible
        progressBar1.Visible = true;
        var worker = new BackgroundWorker();

        // Event that runs on background
        worker.DoWork += this.Worker_DoWork;

        // Event that will run after the background event as finnished
        worker.RunWorkerCompleted += this.Worker_RunWorkerCompleted;
        worker.RunWorkerAsync();
    }

    // The reason for having this here was to work with the progress bar and to search for the photos and it will not block the UI Thread
    // My advice is to have them here and pass them to the next form with a constructor
    private void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        // We must create a list for all the files that the search it will find
        List<string> filesList = new List<string>();
        // Create the new DataTable to be used
        tableWithPhotos = new DataTable();      
        tableWithPhotos.Columns.Add("Nome e formato do ficheiro (duplo clique para visualizar a imagem)");
        tableWithPhotos.Columns.Add("Caminho ( pode ser copiado Ctrl+C )");

        // What folders that we want to search for the files
        var diretorios = new List<string>() { @"\\Server\folder1\folder2" };

        // What extensions that we want to search
        var extensoes = new List<string>() {"*.jpg","*.bmp","*.png","*.tiff","*.gif"};

        // This 2 foreach are to search for the files with the extension that is on the extensoes and on all directories that are on diretorios
        // In for foreach we go through all the extensions that we want to search
        foreach (string entryExtensions in extensoes)
        {
            // Now we must go through all the directories to search for the extension that is on the entryExtensions
            foreach (string entryDirectory in diretorios)
            {
                // SearchOption.AllDirectories search the directory and sub directorys if necessary
                // SearchOption.TopDirectoryOnly search only the directory
                filesList.AddRange(Directory.GetFiles(entryDirectory, entryExtensions, SearchOption.AllDirectories));
            }
        }

        // And now here we will add all the files that it has found into the DataTable
        foreach (string entryFiles in filesList)
        {
            DataRow row = tableWithPhotos.NewRow();
            row[0] = Path.GetFileName(entryFiles);
            row[1] = entryFiles;
            tableWithPhotos.Rows.Add(row);
        }
    }
    private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // With the new constructor on the FormResultadosFotos, we pass the table like this so the form can receive it
        progressBar1.Visable = false;
        var NovoForm = new FormResultadosFotos(tableWithPhotos);
        NovoForm.Show();
    }
}

在FormResultadosFotos上,我们创建了一个新的构造函数,该构造函数将接收DataTable并消除在此处搜索文件的需要,因为它们都已经在表上准备好了

On the FormResultadosFotos we create a new constructor that will receive the DataTable and remove the need to search for the files here, since they are all ready on the on the table

public partial class FormResultadosFotos : Form
{
    // This is the constructor that we have added to the FormResultadosFotos so it can receive the DataTable that was created on the previous form
    Public FormResultadosFotos(DataTable table)
    {
        InitializeComponent();
        dataGridView1.DataSource = table;
        dataGridView1.Columns[1].Visible = true;
        // What can be done here to not block the UI thread if is being blocked while populating the dataGridView1, is to create another BackgroundWorker here and populate the dataGridView1 there
    }

    private void dataGridView1_DoubleClick(object sender, EventArgs e)
    {
        var myForm = new FormPictureBox();
        string imageName = dataGridView1.CurrentRow.Cells[1].Value.ToString();
        var img = Image.FromFile(imageName);

        myForm.pictureBox1.Image = img;
        myForm.ShowDialog();
    }
}

要使progressBar1从1到100,它需要您在搜索之前知道有多少文件,并且在搜索之前知道,因为我们不知道将其从1转到100. 100,这是不可能的,至少据我所知,如果可能的话,请为此创建一个答案,因为我想知道如何

To have the progressBar1 to go from 1 to 100, it would require for you to know before the search how many files there was and such before the search, since we don't know that, having it to go from 1 to 100 its impossible, at least from my knowledge, if it is possible please create an anwser for this since I would like to know how

具有这样的功能(您必须在FormResultadosFotos类中必须具有其他方法,至少要具有基本构造函数),它将按照您的意愿进行操作,搜索可能花费很长时间的文件是在新的线程AKA BackgroundWorker上完成的并且如果列表diretorios中的目录内有任何"*.jpg","*.bmp","*.png","*.tiff","*.gif"文件,它将被放置在列表filesList中,依此类推,可以将foreach添加到DataTable

Having it like this (you must have other methods inside the Class FormResultadosFotos, at least the base constructor) it will do what you want, the search for the files that can take a long time is done on a new Thread AKA BackgroundWorker and if there are any "*.jpg","*.bmp","*.png","*.tiff","*.gif" files inside the directories that are on the List diretorios it will put them on the List filesList so on is foreach can be added to the DataTable

即使是我自己做葡萄牙语,也只是一点建议,在这里提问时,尽量不要用葡萄牙语输入内容,使用英语,例如注释和变量,这样会使您的代码阅读起来更加容易.

Even being portuguese myself, just a little advice, when asking a question here, try not to put stuff in portuguese, use english, like comments and variables it makes more easy to read your code.

使用我提供的代码,您可以从图片中看到:

With the code I provided you its working, as you can see from the picture :

这是程序的链接下载链接

从与我共享的信息中可以看到,应该可以解决您确实遇到的问题,请参阅我为您提供的示例所做的程序源代码

As you can see from the info that I shared with you should resolve the problem that you did have, see the source code of the program I did make with the example I provided for you

这篇关于搜索照片和进度条显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆