Tôi có Biểu mẫu trong ứng dụng của tôi hiển thị một số dữ liệu. Khi tôi lần đầu tiên hiển thị biểu mẫu, tôi tải một số dữ liệu vào một DataTable sau đó liên kết DataTable với một DataGridView. Tôi cũng bắt đầu một phương thức không đồng bộ thực hiện một số truy vấn cơ sở dữ liệu chậm hơn. Khi các truy vấn này chậm hoàn thành, tôi cần phải cập nhật một vài trăm hàng trong DataTable, điền vào các giá trị trở về từ các truy vấn chậm, như vậy:tối ưu hóa các cập nhật cho DataTable được ràng buộc với DataGridView
foreach (DataRow row in data.Rows)
{
SlowLoadingData slow_stuff = slow_query_results[(int)row["id"]];
row.BeginEdit();
row[column_one] = slow_stuff.One;
row[column_two] = slow_stuff.Two;
row[column_three] = slow_stuff.Three;
row.EndEdit();
}
này là cực kỳ chậm, treo thread UI trong một phút hoặc nhiều hơn, có lẽ vì mỗi hàng đang kích hoạt vẽ lại.
Sau một số nghiên cứu, tôi đã tìm ra cách để thực hiện nhanh chóng. Đầu tiên, ràng buộc DataGridView với một BindingSource ràng buộc với DataTable, thay vì trực tiếp đến DataTable. Sau đó, hãy làm như sau khi bạn thực hiện thay đổi đối với DataTable:
binding_source.SuspendBinding();
binding_source.RaiseListChangedEvents = false;
// foreach (DataRow in Data.Rows) ... code above
binding_source.RaiseListChangedEvents = true;
binding_source.ResumeBinding();
grid.Refresh();
Có một vấn đề, tuy nhiên, và đó là một doozy: mã trên ngăn DataGridView từ phát hiện hàng mới được thêm vào DataTable. Bất kỳ hàng mới nào được thêm vào bảng sẽ không xuất hiện trong lưới. Lưới cũng có thể ném ngoại lệ nếu bạn sử dụng các phím mũi tên để di chuyển lựa chọn ô hiện tại khỏi đầu dưới của lưới, vì nguồn dữ liệu cơ bản có nhiều hàng hơn nhưng lưới không tạo hàng lưới để hiển thị chúng.
Vì vậy, hai giải pháp khả thi mà tôi có thể thấy:
Có cách nào tốt hơn để ngăn chặn cập nhật ràng buộc khi thực hiện thay đổi đối với DataTable tiềm ẩn?
Có cách nào dễ dàng để cho DataGridView làm mới bộ sưu tập hàng lưới của nó một cách duyên dáng để phù hợp với số lượng các hàng DataTable cơ bản không? (Lưu ý: Tôi đã cố gắng gọi BindingSource.ResetBindings, nhưng có vẻ như để kích hoạt nhiều trường hợp ngoại lệ nếu bạn có loại bỏ hàng từ DataTable)
Tôi không biết nhiều về việc sử dụng nguồn ràng buộc nhưng thực hiện quá trình khôi phục trước khi đặt raiselistchangedevents thành sự thật có khác biệt gì không? – eglasius
Tôi đã thử tất cả các lệnh có thể gọi các phương thức. Tất cả những gì được yêu cầu cho lưới để vít lên là RaiseListChangedEvents là sai khi hàng mới được thêm vào. –
Gọi hàm có tên ResetBindings để buộc giao diện người dùng cập nhật. – CodingBarfield