【发布时间】:2019-02-03 00:14:19
【问题描述】:
我正在尝试开发一个允许我搜索照片、在DataGridView 中列出并在PictureBox 中预览的应用程序。
现在我必须指出的目录有问题。如果我把同一个目录放在两个Forms中,ProgressBar没有结束,搜索结果也不会出现。
但是如果我从FormProcuraFotosForm 中删除路径,结果已经出现但ProgressBar 不能正常工作。
为了简化流程,我必须对代码进行哪些更改?
FormProcuraFotos代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _myprog
{
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>() {@"\\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.Visible = false;
var NovoForm = new FormResultadosFotos(tableWithPhotos);
NovoForm.Show();
}
}
}
FormResultadosFotos代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace _myprog
{
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();
}
public FormResultadosFotos()
{
InitializeComponent();
}
private void FormFotos_Load(object sender, EventArgs e)
{
// se pretendermos pesquisar em várias pastas
List<string> diretorios = new List<string>()
{@"\\server\folder1\folder2"};
// se pretendermos pesquisar as várias extensões
List<string> extensoes = new List<string>()
{".jpg",".bmp",".png",".tiff",".gif"};
DataTable table = new DataTable();
table.Columns.Add("Nome e formato do ficheiro (duplo clique para visualizar a imagem)");
table.Columns.Add("Caminho ( pode ser copiado Ctrl+C )");
foreach (string diretorio in diretorios)
{
var ficheiros = Directory.EnumerateFiles(diretorio, "*", SearchOption.AllDirectories).
Where(r => extensoes.Contains(Path.GetExtension(r.ToLower())));
foreach (var ficheiro in ficheiros)
{
DataRow row = table.NewRow();
row[0] = Path.GetFileName(ficheiro);
row[1] = ficheiro;
table.Rows.Add(row);
}
}
dataGridView1.DataSource = table;
dataGridView1.Columns[1].Visible = true;
}
}
}
谢谢。
【问题讨论】:
-
您正在搜索照片两次,一次是在后台进程中,然后是在加载完成后打开的表单时,在我看来这是多余的。什么需要搜索两次相同的目录?!试图理解这一点
-
我试图表明,如果我从 FormProcuraFotos 中删除搜索目录,进度条不会显示为正在运行。您可以编辑我在帖子中输入的代码吗?我知道我不需要进行冗余搜索。只是试图显示我的问题。
-
如果您从
FormProcuraFotos中删除搜索,当然它不会显示任何进度条,因为它什么都不做,并且需要几毫秒来运行这部分代码。就像我多次告诉你的那样,背景(不会谈论线程类等,因为它很明显你甚至缺少基础知识)是在后台做繁重的事情,所以它不会阻塞主线程 AKA UI 同时做它需要的繁重的东西。这将是我最后一次解决这个问题,检查我给你的例子,100% 符合你的要求 -
好的。解决了。谢谢大家。