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,

Другие вопросы по тегам