2011-03-14 56 views
1

我有一個WinForms應用程序,它包含一個Dataset ds和一個DataGridView dgv。 dgv綁定到ds。當DataGridView可編輯時,DataGridView/Dataset的線程安全更新

ds通過Task()來更新,Task()使用TableAdapter.Fill()方法定期查詢數據庫。我在這裏遇到兩個問題。

  1. 當更新ds時,除非窗口被調整大小或其他某個事件導致窗體重繪,否則不會刷新dgv。

  2. 當用戶開始編輯dgv中的單元格時,由於多個線程訪問相同的GUI控件,ds被更新並導致UI崩潰。我試圖使用一個標誌EditModeOn,它由DataGridView dgv中的某些事件設置,雖然這沒有幫助防止線程錯誤。

什麼是具有可以由用戶進行編輯,並通過修改綁定數據集(在另一個線程更新)更新一個DataGridView的最佳方式?

回答

1

在第1點,您可以通過撥打Form.Invalidate()來解決這個問題。這將導致你的表單重新繪製自己;這有點骯髒,但它應該做的伎倆。

在#2點上,如果你有一個任務正在從另一個線程更新控件的內容,那麼你應該總是得到一個異常,因爲從UI以外的任何線程訪問控件是非法的線程(UI創建的線程)。所以我不清楚你是如何做到這一點的。

但是,我會做的是使用線程檢索結果,然後將這些結果存儲在成員變量(字段)中。然後定期檢查該字段以查看數據是否需要刷新,以及如果從該字段獲取數據並將其放入網格,然後將該字段清空。您可以使用System.Windows.Forms.Timer類的Tick事件來實施此定期檢查。

在您的更新例程中,您可以檢查您的標誌以查看網格是否正在編輯,並在稍後再忽略更新。

+0

什麼是DataGridView類的正確標誌或成員變量來檢查網格是否正在編輯? – DonQuixote 2011-03-14 17:32:29

+0

對不起,點擊輸入太快 - 我的其他評論是關於我如何更新DataGridView。我的線程只是更新DataSet,它綁定到DataGridView(它不直接調用刷新或重繪方法,只是修改基礎數據集)。 – DonQuixote 2011-03-14 17:33:24

+0

該標誌有點不相干,只要將布爾字段設置爲「true」就足夠了。如果數據網格綁定到該數據集,並且您更新了不同線程上的數據集,並且該更新觸發了需要更新的網格通知;所有這些都發生在導致交叉線程異常的'後臺線程'的上下文中。有時候人們很難跟隨。 – CodingGorilla 2011-03-14 19:00:05

2

對於您的要點#2,您可以使用Control類中的功能Invoke。該函數將在UI線程中執行該函數。

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

Ex。 :

// Invoke an anonymous method on the thread of the form. 
this.Invoke((MethodInvoker) delegate 
{ 
    //Call your function to update your datagridview with the dataset in parameters 
    ... 
});