在另一个 class 内增加 ProgressBar
Increment ProgressBar within another class
这是我在这里问的第一个问题,所以请多多关照 ;)
所以我目前正在编写的 C# 应用程序中实际上有两个 WinForms(我对 C# 很陌生)。
这个window有一个按钮,可以将您之前在列表框中选择的USB设备中的照片保存到另一个文件夹中。
单击此按钮后,我的主线程当然忙于复制,因此我决定创建另一个包含 ProgressBar 的 WinForm。
对于每个完成的副本,我想相应地增加 ProgressBar。
所以我计算了我必须做的份数,并将进度条设置为最大值。但我现在的问题是,我真的不知道如何在不出现线程不安全异常的情况下增加 ProgressBar。
这是我的 ProgressWindow 代码:
public partial class ProgressWindow : Form
{
BackgroundWorker updateProgressBarThread = new BackgroundWorker();
private Boolean _isThreadRunning = false;
public Boolean IsThreadRunning
{
get { return _isThreadRunning; }
set { _isThreadRunning = value; }
}
private int _progressbarLength;
public int ProgressbarLength
{
get { return _progressbarLength; }
set { _progressbarLength = value; }
}
private int progress = 1;
public ProgressWindow()
{
Show();
InitializeComponent();
}
private void StartUpdateThread(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
// Reports progress to the ProgressChangedEvent function. (Thread Safe)
}
private void FinishProgressThread(object sender, RunWorkerCompletedEventArgs e)
{
if (!_isThreadRunning)
{
MessageBox.Show("Erfolgreich kopiert");
Close();
}
}
private void ProgressChangedEvent(object sender, ProgressChangedEventArgs e)
{
this.copyProgressbar.Value = e.ProgressPercentage;
this.progressStatus.Text = e.ProgressPercentage.ToString();
}
public void CallUpdateThread()
{
updateProgressBarThread.WorkerReportsProgress = true;
updateProgressBarThread.DoWork += new DoWorkEventHandler(StartUpdateThread);
updateProgressBarThread.ProgressChanged += new ProgressChangedEventHandler(ProgressChangedEvent);
updateProgressBarThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(FinishProgressThread);
updateProgressBarThread.RunWorkerAsync();
}
}
我想在每次成功复制后将 ProgressBar 增加 1。
我如何从我的主线程执行此操作?
这是实际处理复制过程的函数
private void SaveFile(System.IO.DirectoryInfo root)
{
try
{
IEnumerable<DirectoryInfo> directoriesNames = root.EnumerateDirectories();
// New instance of thread ProgressWindow.
ProgressWindow progress = new ProgressWindow();
progress.CallUpdateThread();
foreach (DirectoryInfo element in directoriesNames)
{
// Query all subdirectories and count everything with the in the configuration made settings.
if (!element.Attributes.ToString().Contains("System"))
{
// Now we insert the configuration we applied.
String fileExtension = null;
if (Properties.Settings.Default._configPhoto)
{
fileExtension = "*.jpg";
}
if (Properties.Settings.Default._configWordDocument)
{
fileExtension = "*.odt";
}
FileInfo[] jpgList = element.GetFiles(fileExtension, SearchOption.AllDirectories);
// set the size of the progress bar
progress.ProgressbarLength = jpgList.Count();
// Now we go through all our results and save them to our backup folder.
foreach (FileInfo tmp in jpgList)
{
string sourceFilePath = tmp.FullName;
string destFilePath = PATHTOBACKUP + "\" + tmp.Name;
progress.IsThreadRunning = true;
try
{
System.IO.File.Copy(sourceFilePath, destFilePath, true);
}
catch (IOException ioe)
{
MessageBox.Show(ioe.Message);
}
}
}
}
// progress.IsThreadRunning = false;
}
catch (UnauthorizedAccessException e)
{
MessageBox.Show(e.Message);
}
}
很明显我必须在这个函数之后做这个
System.IO.File.Copy(sourceFilePath, destFilePath, true);
但是我该如何将此报告给我的 ProgressWindow?
我真的希望我解释得足够好,不确定我是否遗漏了一些重要的东西。
提前谢谢大家
以下是关键组件的紧凑示例:
- 点击按钮启动新的线程工作者
- 进度取决于文件长度,而不是文件数量
用于更新进度条的BeginInvoke(避免跨线程异常)
ProgressBar pb = new ProgressBar() { Minimum = 0, Maximum = 100 };
Button btn = new Button();
btn.Click += delegate {
Thread t = new Thread(() => {
DirectoryInfo dir = new DirectoryInfo("C:\temp\");
var files = dir.GetFiles("*.txt");
long totalLength = files.Sum(f => f.Length);
long length = 0;
foreach (var f in files) {
length += f.Length;
int percent = (int) Math.Round(100.0 * length / totalLength);
pb.BeginInvoke((Action) delegate {
pb.Value = percent;
});
File.Copy(f.FullName, "...");
}
});
t.IsBackground = true;
t.Start();
};
这是我在这里问的第一个问题,所以请多多关照 ;)
所以我目前正在编写的 C# 应用程序中实际上有两个 WinForms(我对 C# 很陌生)。
这个window有一个按钮,可以将您之前在列表框中选择的USB设备中的照片保存到另一个文件夹中。 单击此按钮后,我的主线程当然忙于复制,因此我决定创建另一个包含 ProgressBar 的 WinForm。
对于每个完成的副本,我想相应地增加 ProgressBar。
所以我计算了我必须做的份数,并将进度条设置为最大值。但我现在的问题是,我真的不知道如何在不出现线程不安全异常的情况下增加 ProgressBar。
这是我的 ProgressWindow 代码:
public partial class ProgressWindow : Form
{
BackgroundWorker updateProgressBarThread = new BackgroundWorker();
private Boolean _isThreadRunning = false;
public Boolean IsThreadRunning
{
get { return _isThreadRunning; }
set { _isThreadRunning = value; }
}
private int _progressbarLength;
public int ProgressbarLength
{
get { return _progressbarLength; }
set { _progressbarLength = value; }
}
private int progress = 1;
public ProgressWindow()
{
Show();
InitializeComponent();
}
private void StartUpdateThread(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
// Reports progress to the ProgressChangedEvent function. (Thread Safe)
}
private void FinishProgressThread(object sender, RunWorkerCompletedEventArgs e)
{
if (!_isThreadRunning)
{
MessageBox.Show("Erfolgreich kopiert");
Close();
}
}
private void ProgressChangedEvent(object sender, ProgressChangedEventArgs e)
{
this.copyProgressbar.Value = e.ProgressPercentage;
this.progressStatus.Text = e.ProgressPercentage.ToString();
}
public void CallUpdateThread()
{
updateProgressBarThread.WorkerReportsProgress = true;
updateProgressBarThread.DoWork += new DoWorkEventHandler(StartUpdateThread);
updateProgressBarThread.ProgressChanged += new ProgressChangedEventHandler(ProgressChangedEvent);
updateProgressBarThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(FinishProgressThread);
updateProgressBarThread.RunWorkerAsync();
}
}
我想在每次成功复制后将 ProgressBar 增加 1。 我如何从我的主线程执行此操作?
这是实际处理复制过程的函数
private void SaveFile(System.IO.DirectoryInfo root)
{
try
{
IEnumerable<DirectoryInfo> directoriesNames = root.EnumerateDirectories();
// New instance of thread ProgressWindow.
ProgressWindow progress = new ProgressWindow();
progress.CallUpdateThread();
foreach (DirectoryInfo element in directoriesNames)
{
// Query all subdirectories and count everything with the in the configuration made settings.
if (!element.Attributes.ToString().Contains("System"))
{
// Now we insert the configuration we applied.
String fileExtension = null;
if (Properties.Settings.Default._configPhoto)
{
fileExtension = "*.jpg";
}
if (Properties.Settings.Default._configWordDocument)
{
fileExtension = "*.odt";
}
FileInfo[] jpgList = element.GetFiles(fileExtension, SearchOption.AllDirectories);
// set the size of the progress bar
progress.ProgressbarLength = jpgList.Count();
// Now we go through all our results and save them to our backup folder.
foreach (FileInfo tmp in jpgList)
{
string sourceFilePath = tmp.FullName;
string destFilePath = PATHTOBACKUP + "\" + tmp.Name;
progress.IsThreadRunning = true;
try
{
System.IO.File.Copy(sourceFilePath, destFilePath, true);
}
catch (IOException ioe)
{
MessageBox.Show(ioe.Message);
}
}
}
}
// progress.IsThreadRunning = false;
}
catch (UnauthorizedAccessException e)
{
MessageBox.Show(e.Message);
}
}
很明显我必须在这个函数之后做这个
System.IO.File.Copy(sourceFilePath, destFilePath, true);
但是我该如何将此报告给我的 ProgressWindow?
我真的希望我解释得足够好,不确定我是否遗漏了一些重要的东西。
提前谢谢大家
以下是关键组件的紧凑示例:
- 点击按钮启动新的线程工作者
- 进度取决于文件长度,而不是文件数量
用于更新进度条的BeginInvoke(避免跨线程异常)
ProgressBar pb = new ProgressBar() { Minimum = 0, Maximum = 100 }; Button btn = new Button(); btn.Click += delegate { Thread t = new Thread(() => { DirectoryInfo dir = new DirectoryInfo("C:\temp\"); var files = dir.GetFiles("*.txt"); long totalLength = files.Sum(f => f.Length); long length = 0; foreach (var f in files) { length += f.Length; int percent = (int) Math.Round(100.0 * length / totalLength); pb.BeginInvoke((Action) delegate { pb.Value = percent; }); File.Copy(f.FullName, "..."); } }); t.IsBackground = true; t.Start(); };