我有以下C#代码显示进度条:
{
public partial class FormPesquisaFotos : Form
{
public FormPesquisaFotos()
{
InitializeComponent();
}
private void FormPesquisaFotos_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
//Mostra a barra de progresso da pesquisa
while (progressBar1.Value < 100)
progressBar1.Value += 1;
{
//Criar um objeto (instância, cópia) da classe FormResultadosFotos
FormResultadosFotos NovoForm = new FormResultadosFotos();
NovoForm.Show();
}
}
}
}
它仅在搜索结束时加载(单击按钮后)。如何在搜索开始时运行进度条?
这是在新表格上显示结果的代码。进度栏停止在95%,几秒钟后显示结果。
{
public partial class FormResultadosFotos : Form
{
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\folder01\folder02"};
// 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;
}
private void dataGridView1_DoubleClick(object sender, EventArgs e)
{
FormPictureBox myForm = new FormPictureBox();
string imageName = dataGridView1.CurrentRow.Cells[1].Value.ToString();
Image img;
img = Image.FromFile(imageName);
myForm.pictureBox1.Image = img;
myForm.ShowDialog();
}
}
}
谢谢。
答案 0 :(得分:2)
您在这里描述的是一个多线程问题。 您的循环在UI有机会更新之前运行。
您应该查看https://stephenhaunts.com/2014/10/14/using-async-and-await-to-update-the-ui-thread/,以获取有关在循环中如何更新UI的说明和示例。
致谢
答案 1 :(得分:2)
您必须在新线程而不是主线程上拥有它。
这是一个小例子:
private void buttonWorkerTest_Click(object sender, RoutedEventArgs e)
{
this.progressBarWorkerTest.Value = 0;
BackgroundWorker worker = new BackgroundWorker();
// Event for the method that will run on the background
worker.DoWork += this.Worker_DoWork;
// Event that will run after the BackgroundWorker finnish
worker.RunWorkerCompleted += this.Worker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
Dispatcher.Invoke(new Action(() =>
{
this.progressBarWorkerTest.Value = i;
}));
Thread.Sleep(100);
}
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// You can put the code here to open the new form and such
}
Dispacher.Invoke
是因为它在WPF上,对于WinForm,只需将其更改为this.Invoke
此示例是,单击按钮后将启动BackgroundWorker,将for设置为1到100,它将休眠100毫秒并更新进度条。
希望这会有所帮助
编辑
现在在示例中包括了在BackgroundWorker完成时运行的事件,以防万一是否需要
编辑2:
我的建议是,在背景上搜索照片时,将它们全部插入到DataTable中,因为您已经准备好搜索它们并且可以在此处完成工作,然后只需在FormResultadosFotos上构造一个构造函数即可接收到数据表。
根据我的理解,主要目标是以FormPesquisaFotos形式搜索它们(这就是为什么我们在那里有背景工作人员进行搜索并更新ProgressBar的原因),并以新的形式AKA FormResultadosFotos显示它们。 >
// Lets create a DataTable variable to be access on the Worker_DoWork and then on the Worker_RunWorkerCompleted
private DataTable tableOfPhotos;
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
// Search for the photos here and then add them to the DataTable
this.tableOfPhotos = new DataTable();
tableOfPhotos.Columns.Add("Nome e formato do ficheiro (duplo clique para visualizar a imagem)");
tableOfPhotos.Columns.Add("Caminho ( pode ser copiado Ctrl+C )");
foreach (string diretorio in diretorios)
{
// se pretendermos pesquisar em várias pastas
List<string> diretorios = new List<string>()
{@"\\Server\folder01\folder02"};
// se pretendermos pesquisar as várias extensões
List<string> extensoes = new List<string>()
{"*.jpg","*.bmp","*.png","*.tiff","*.gif"};
var ficheiros = Directory.EnumerateFiles(diretorio, "*", SearchOption.AllDirectories).
Where(r => extensoes.Contains(Path.GetExtension(r.ToLower())));
foreach (var ficheiro in ficheiros)
{
DataRow row = tableOfPhotos.NewRow();
row[0] = Path.GetFileName(ficheiro);
row[1] = ficheiro;
tableOfPhotos.Rows.Add(row);
}
}
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// You can put the code here to open the new form and such
FormResultadosFotos NovoForm = new FormResultadosFotos(this.tableOfPhotos);
NovoForm.Show();
}
// Constructor that will receive the DataTable and put it into the dataGridView1, it should be added on the Form FormResultadosFotos
Public FormResultadosFotos(DataTable table)
{
InitializeComponent();
// In here we will tell the where is the source for the dataGridView1
this.dataGridView1.DataSource = table;
}
在这里,您还可以通过在行this.dataGridView1.DataSource = table;
上放置一个断点来查看表的含义,如果表为空,则表中没有任何内容(也许目录中没有照片?可以吗?不能访问它吗?不在工作并且没有任何IDE,只是根据我脑海中的想法而定,但是如果需要,您也可以将文件保存在模拟代码中:
List<string> tempList = new List<string>;
foreach (string entryExt in extensoes)
{
foreach (string entryDir in diretorios)
{
// SearchOption.AllDirectories search the directory and sub directorys if necessary
// SearchOption.TopDirectoryOnly search only the directory
tempList.AddRange(Directory.GetFiles(entryDir, entryExt, SearchOption.AllDirectories));
}
}
// Here would run all the files that it has found and add them into the DataTable
foreach (string entry in tempList)
{
DataRow row = tableOfPhotos.NewRow();
row[0] = Path.GetFileName(entry);
row[1] = entry;
tableOfPhotos.Rows.Add(row);
}
编辑3:
更改代码
List<string> extensoes = new List<string>(){".jpg",".bmp",".png",".tiff",".gif"};
到
List<string> extensoes = new List<string>(){"*.jpg","*.bmp","*.png","*.tiff","*.gif"};
您需要在扩展名前加*(例如.png)来搜索该扩展名的文件