Я заполняю DataGridView
, запустив SQL-запрос с BackgroundWorker
.Мой код работает отлично, если я запускаю его непосредственно в обработчике событий кнопки, но когда я вставляю DoWork
BackgroundWorker, он не обновляет пользовательский интерфейс.Мой код ниже.
DataTable tab1table = new DataTable();
public Form1()
{
InitializeComponent();
Instantiatesearch1Thread();
}
private void Instantiatesearch1Thread()
{
search1Thread.WorkerReportsProgress = true;
search1Thread.WorkerSupportsCancellation = true;
search1Thread.ProgressChanged += search1Thread_ProgressChanged;
search1Thread.DoWork += search1Thread_Dowrk;
search1Thread.RunWorkerCompleted += search1Thread_RunWorkerCompleted;
}
private void sbutton1_Click(object sender, EventArgs e)
{
search1Thread.RunWorkerAsync();
}
void search1Thread_Dowrk(object sender, DoWorkEventArgs e)
{
int percentprogress = 0;
percentprogress++;
Thread.Sleep(1000);
// Search1 button event handler
using (SqlConnection conn = new SqlConnection(connectionstring))
{
conn.Open();
using (SqlDataAdapter cmd = new SqlDataAdapter(comboBox1SQL, conn))
{
if (comboBox1.Text.Contains("ID"))
{
long para = long.Parse(search1.Text);
cmd.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "@combo1Par",
Value = para,
SqlDbType = SqlDbType.BigInt
});
}
else if (comboBox1.Text.Contains("Other Thing") || comboBox1.Text.Contains("Other Stuff"))
{
string para = search1.Text;
cmd.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "@combo1Par",
Value = "%" + para + "%",
SqlDbType = SqlDbType.NVarChar,
});
}
// Clear datatable if it contains any information and then fill it
// tab1datatable is a DataGridView
if (tab1table != null)
tab1table.Clear();
cmd.Fill(tab1table);
//tab1datatable.DataSource = tab1table;
// A bunch of expensive calculations
}
}
}
void search1Thread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
search1Progress.Value = e.ProgressPercentage;
}
void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
tab1datatable.DataSource = tab1table;
tab1datatable.Refresh();
MessageBox.Show("All Done!");
}
Используя MessageBox
, я обнаружил, что код не обращается к операторам if comboBox1.Text.Contains()
, что, я думаю, имеет смысл, поскольку эта информация поступает из пользовательского интерфейса и BackgroundWorker
не может напрямую получить доступ к интерфейсу.Это также объясняет, почему тогда tab1datatable
и tab1table
остаются нетронутыми.
Я думаю, что мне нужно где-то использовать метод Invoke
, но я не уверен, как это сделать.Я взглянул на c # - Передача информации в BackgroundWorker из пользовательского интерфейса во время выполнения , но на самом деле он не отвечает на мой вопрос.Если Invoke
- это то, что мне нужно, как я могу реализовать в этом коде, чтобы он мог получать информацию из пользовательского интерфейса и впоследствии обновлять ее, заполняя DataGridView
?