Заполнить dataGridView благодарю backGroundWorker - PullRequest
5 голосов
/ 27 июня 2010

У меня есть фрагмент кода:

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        remplirDataGrid();
    }

private void frmChercherActesLoad(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();

        }



 private void remplirDataGrid()
        {
            dataGridView1.DataSource = ActeServices.getAllActes(0, 40);
            dataGridView1.Columns[0].Visible = false;
            dataGridView1.Columns[1].HeaderText = "Code acte";
            dataGridView1.Columns[2].HeaderText = "Désignation";
            dataGridView1.Columns[3].HeaderText = "Pris en charge";
            dataGridView1.Columns[4].HeaderText = "Id article";
            dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
        }

А вот метод getAllActe:

public static IEnumerable<Acte> getAllActes(int skipCount, int takeCount)
        {
            var myTableAdapter = new SmartDocDALServices.SmartDocDataSetTableAdapters.actesTableAdapter();
            myTableAdapter.Fill(myDataSet.actes);
            var myResult = from q in myDataSet.actes.AsEnumerable()
                            select new Acte
                            {
                                code = q.code,
                                designation = q.designation,
                                priseEnCharge = q.prise_en_charge,
                                idArticle = q.id_article,
                            };

            if (skipCount != -1)
                myResult.Skip(skipCount);
            if (takeCount != -1)
                myResult.Take(takeCount);
            IEnumerable<Acte> myResultRet = myResult.ToList();
            return myResultRet;

Мне нравится заполнять мой datagridview, используяФоновый рабочий, как только я запустил приложение, я получил эту ошибку:

Недопустимая операция между потоками: элемент управления 'dataGridView1 был объектом доступа из потока, отличного от того, который был создан.1012 *


Я пробую это

 private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
      IEnumerable<Acte> result = ActeServices.getAllActes(0, 40);
       backgroundWorker1.ReportProgress(0, result);

    }

    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

      dataGridView1.DataSource = (IEnumerable<Acte>)e.UserState;
      dataGridView1.Columns[0].Visible = false;
      dataGridView1.Columns[1].HeaderText = "Code acte";
     ***

, но ничего не получилось со временем ?.Я хотел бы, чтобы обновление сетки данных, когда BGW загружает данные, предварительно загружает данные, добавляет его в DGV

.

Ответы [ 4 ]

3 голосов
/ 27 июня 2010

Это потому, что содержимое графического интерфейса нельзя изменить из других потоков, кроме потока графического интерфейса.Чтобы это исправить, вам нужно вызвать изменения в потоке GUI с помощью Dispatcher.

DataGrid должен быть настроен заранее, поэтому все, что вы делаете в асинхронной операции, - это заполняете данные.*

3 голосов
/ 27 июня 2010

DataGridView не является потокобезопасным. Однако установка источника данных, если данные уже доступны, должна быть достаточно быстрой.

Я бы порекомендовал:

  1. Используйте только BackgroundWorker для загрузки данных в другой поток

  2. Установите DataSource и другие модификации представления данных в событии RunWorkerCompleted (вы можете передать результат из метода DoWork в событие Completed, установив

    e.Result = ActeServices.getAllActes (0, 40);

  3. Необязательно: Установите для dataGridView1.AutoGenerateColumns значение false и вручную добавьте столбцы либо в конструкторе форм Windows, либо в коде, чтобы избежать мерцания.

3 голосов
/ 27 июня 2010

Вы не можете обновить пользовательский интерфейс из потока BackgroundWorker.

Вам необходимо отправить событие в пользовательский интерфейс и затем получить что-то вроде:

private void EventHandler(object sender, YourEventArgs e)
{
    if (this.dataGridView1.InvokeRequired)
    {
        this.dataGridView1.Invoke((MethodInvoker)delegate { this.AddToGrid(e.YourData); });
    }
    else
    {
        this.AddToGrid(e.YourData);
    }
}
0 голосов
/ 27 июня 2010

Класс BackgroundWorker был разработан для запуска длительной операции в фоновом потоке.Поскольку вам разрешен доступ к компонентам пользовательского интерфейса только из потока, который их создал, вы можете использовать событие RunWorkerCompleted класса BackgroundWorker для обновления вашего пользовательского интерфейса после завершения обработки вашего обработчика DoWork.Кроме того, вы можете безопасно обновить пользовательский интерфейс, используя событие ProgressChanged класса BackgroundWorker.

...