问题
I have a Form where one can Sign In and it could take a while till the data gets loaded into the Form. So I wanted to create a seperate Form (loadScreen.cs) with a Progress Bar when the Form is loading. I tried this in the loadScreen.cs Form:
private void Form1_Load(object sender, EventArgs e)
{
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged +=
new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
int percentFinished = (int)e.Argument;
while (!worker.CancellationPending && percentFinished < 100)
{
percentFinished++;
worker.ReportProgress(percentFinished);
System.Threading.Thread.Sleep(50);
}
e.Result = percentFinished;
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Close();
}
I've read that the worker_DoWork method should have the code which takes longer to load. I don't know how to handle this since my button is in Form1. When it's clicked then I go to another class with
private void signIn_Click(object sender, EventArgs e)
{
var logIn = new LogIn(this);
logIn.checkUserInput(this);
}
and there I execute the operations which load certain things. How to connect everything? I need help!
回答1:
I'm actually in the process of creating a general-purpose dialogue for this sort of thing. It's not going to be ready in time to be of use to you but I would suggest that you go along similar lines. Create your "Loading" dialogue so that it accepts a delegate and invokes it in the DoWork
event handler. The main form can then contain a method that does the work and you can pass a delegate for that method to the dialogue. I'll post a very basic example.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private DataTable table;
private void button1_Click(object sender, EventArgs e)
{
var work = new Action(GetData);
using (var f2 = new Form2(work))
{
f2.ShowDialog();
this.dataGridView1.DataSource = this.table;
}
}
private void GetData()
{
this.table = new DataTable();
using (var adapter = new SqlDataAdapter("SELECT * FROM MyTable", "connectionstring here"))
{
adapter.Fill(table);
}
}
}
public partial class Form2 : Form
{
private Action work;
public Form2(Action work)
{
InitializeComponent();
this.work = work;
}
private void Form2_Load(object sender, EventArgs e)
{
this.backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.work();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.DialogResult = DialogResult.OK;
}
}
Note that there's no real way to measure progress when using a data adapter so you could only really display a marquee progress bar in this case.
来源:https://stackoverflow.com/questions/29094016/background-worker-loading-screen-in-winforms