Заполнить данныеGridView спасибо backGroundWorker

109
12

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


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 с помощью рабочего стола фона, как только я запустил приложение, я получил эту ошибку:


Работа с несколькими потоками недействительна: Control 'dataGridView1 был объектом доступа из потока, отличного от того, который был создан.



Я пробую это


 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";
***


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

спросил(а) 2021-01-19T17:55:50+03:00 6 месяцев назад
1
Решение
89

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


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

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


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


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


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


ответил(а) 2021-01-19T17:55:50+03:00 6 месяцев назад
90

Вы не можете обновить пользовательский интерфейс из потока 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);
}
}

ответил(а) 2021-01-19T17:55:50+03:00 6 месяцев назад
89

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


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

var data = ActeServices.getAllActes(0, 40);

Dispatcher.BeginInvoke( new Action( () => { dataGridView1.DataSource = data; }))

ответил(а) 2021-01-19T17:55:50+03:00 6 месяцев назад
46

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

ответил(а) 2021-01-19T17:55:50+03:00 6 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема