BackgroundWorker для извлечения DataBase и помещения его в DataGrid с динамически добавляемыми столбцами
Я прочитал этот вопрос: BackgroundWorker для чтения базы данных и обновления графического интерфейса
И считает, что это хороший способ решить эту проблему. Единственное, что я создаю свои колонки динамически.
Я прочитал schemaInfo из DataBase, чтобы получить ColumnNames и создать DataGridColumn foreach Column в DataBase.
Теперь я хочу сделать это с помощью BackgroundWorker, но вы не можете обновить пользовательский интерфейс с помощью BackgroundWorker.
На данный момент (без BackgroundWorker) у меня есть 2 метода для получения значений базы данных.
Чтобы загрузить столбцы:
using (MySqlDataReader reader = cmd.ExecuteReader())
{
using (DataTable schema = reader.GetSchemaTable())
{
foreach (DataRow col in schema.Rows)
{
DataGridTextColumn column = new DataGridTextColumn();
string columnstring = col.Field<String>("ColumnName");
comboFilter.Items.Add(UppercaseFirst(columnstring));
column.Binding = new Binding(col.Field<String>("ColumnName"));
column.Header = UppercaseFirst(col.Field<String>("ColumnName"));
column.IsReadOnly = true;
Style textStyle = new Style(typeof(TextBlock));
textStyle.Setters.Add(new Setter(TextBlock.TextWrappingProperty, TextWrapping.Wrap));
column.ElementStyle = textStyle;
dataGridPrivatecustomers.Columns.Add(column);
}
}
}
Чтобы загрузить значения
using (MySqlDataAdapter dataAdapter = new MySqlDataAdapter(string.Format("SELECT * FROM {0}", privateCustomerTablename), connection))
{
using (DataTable dt = new DataTable())
{
dataAdapter.Fill(dt);
dataGridPrivatecustomers.ItemsSource = dt.DefaultView;
}
}
Поэтому я попытался сделать оба в одном и изо всех сил пытался создать список результатов для DataSrad DataGrad:
using (MySqlDataReader reader = cmd.ExecuteReader())
{
int i = 0;
while (reader.Read())
{
using (DataTable schema = reader.GetSchemaTable())
{
foreach (DataRow row in schema.Rows)
{
results.Add(new
{
});
i++;
}
}
}
}
Дело в том, что мне нужно знать, как я могу поместить ColumnName + Value в список результатов.
В связанном вопросе он сделал Id = rdr.GetInt32(0),
Но я не могу сделать row.Field<String>("ColumnName") = reader[i].ToString()
Код также не знает, сколько столбцов добавить, поэтому я думаю, что мне нужен еще один цикл for или foreach? И как я могу установить ColumnName?
1 ответ
Я думаю, что некоторые люди тоже хотят это знать, потому что (для меня) это выглядит очень сложно для начинающих разработчиков, которые не хотят отображать столбцы и значения из базы данных в DataGrid с BackgroundWorker.
Поэтому я покажу вам, как я решил свой вопрос.
Сначала я создал список для хранения всех имен столбцов.
private List<string> columnList = new List<string>();
После этого я отредактировал Событие worker_DoWork следующим образом:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
using (MySqlConnection connection = new MySqlConnection(conf.connection_string))
{
if (OpenConnection(connection))
{
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = connection;
cmd.CommandText = string.Format("SELECT * FROM {0}", privateCustomerTablename);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
using (DataTable schemaTable = reader.GetSchemaTable())
{
columnList.Clear();
foreach (DataRow row in schemaTable.Rows)
{
columnList.Add(row.Field<String>("ColumnName"));
}
}
}
using (MySqlDataAdapter dataAdapter = new MySqlDataAdapter(cmd.CommandText, connection))
{
using (DataTable dt = new DataTable())
{
dataAdapter.Fill(dt);
e.Result = dt;
}
}
}
connection.Close();
}
}
}
Сначала вы можете видеть, что я создал DataReader для чтения схемы DataBase и сохранения ее в DataTable, чтобы я мог зациклить ее через цикл foreach. В этом цикле я добавляю каждый элемент из schemaTable в свой список, чтобы список содержал все имена столбцов выбранной таблицы базы данных.
После этого я создал DataAdapter и сохранил содержимое в другой DataTable. И я передаю этот DataTable через e.Result = dt
к worker_RunWorkerCompleted Event
, Теперь я хочу получить доступ к этим данным в моем worker_RunWorkerCompleted Event
,
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
foreach (var item in columnList)
{
DataGridTextColumn column = new DataGridTextColumn();
column.Binding = new Binding(item);
column.Header = UppercaseFirst(item);
column.IsReadOnly = true;
dataGridPrivatecustomers.Columns.Add(column);
}
DataTable dt = e.Result as DataTable;
dataGridPrivatecustomers.ItemsSource = dt.DefaultView;
}
Я зацикливаю все элементы в моем columnList и создаю DataGridTextColumn для каждого элемента в этом списке и добавляю его в свою DataGrid.
После этого все столбцы добавляются в мою DataGrid, и я устанавливаю ItemsSource моей DataGrid в DataTable, из которого я передал worker_DoWork
в worker_RunWorkerCompleted
,