2012-03-06 118 views
1

好吧,新的謎題!非常簡單的概念驗證設置:DataGridView,通過DataTable綁定到SQL視圖。數據是動態的(雖然行#是恆定的),所以我添加了一個​​刷新它:設置DataGridView.FirstDisplayedScrollingRowIndex停止發射定時器?

private DataTable tbData= new DataTable(); 

private void frmMain_Load(object sender, EventArgs e) 
{ 
    LoadData(); 
    oTimer.Start(); 
    MessageBox.Show(oTimer.Enabled.ToString()); 
} 
private void frmMain_DoubleClick(object sender, EventArgs e) 
{ 
    LoadData(); // to reload on-demand - works perfectly 
} 
private void LoadData() 
{ 
    SqlDataAdapter da= 
     new SqlDataAdapter("select * from vwOne", Program.oSqlConn); 

    tbData.Clear(); 
    da.Fill(tbData); 
    dgView.DataSource= tbData; 
} 
private void oTimer_Tick(object sender, EventArgs e) 
{ 
    LoadData(); 
    this.Text+= "|"; 
} 

要刷新期間保持滾動位置我添加下列行(1和2):

private void LoadData() 
{ 
    SqlDataAdapter da= 
     new SqlDataAdapter("select * from vwOne", Program.oSqlConn); 

    int iRow= dgView.FirstDisplayedScrollingRowIndex; // 1-remember row 

    tbData.Clear(); 
    da.Fill(tbData); 
    dgView.DataSource= tbData; 

    dgView.FirstDisplayedScrollingRowIndex=  iRow; // 2-restore back 
} 

到目前爲止好。現在這裏的踢球者:沒有第2行重新加載完美(不保留滾動),但只要我取消註釋第2行計時器剛剛停止(oTimer_Tick中的斷點從未被擊中)!?

什麼給!?

編輯:frmMain_DoubleClick(..)添加到上面的代碼(已經有了它,並已使用),它工作正常; 絕對沒有拋出異常,並且沒有SQL連接問題。從字面上看,取消註釋該行(#2)使完全不同,在oTimer_Tick中觀察到完全不被調用!

繼建議(謝謝你們!)我加幾行新命令:

  • frmMain_Load(..)顯示oTimer.Enabled並確認其完成到最後,
  • 和附加一個「| 「每次oTimer_Tick(..)觸發時形成標題。

沒有第2行的執行如預期的那樣:message-box表示'真',標題不斷增加新的'|'。取消註釋第2行,並且沒有消息框!?,沒有標題更新,但沒有任何例外!?這是直接從VS2010以調試模式運行,可以調試器吞下任何異常(我從來沒有見過這種情況)?估計,因爲沒有消息框顯示這表示問題是啓動計時器,=>它不會觸發。但就像我說的,唯一的變化就是取消註釋第2行..它如何/爲什麼會影響計時器!?

好的,接下來的嘗試將通過動態切換(例如通過複選框)來避免重新編譯是否保留滾動位置,其餘的可視化處理,也許這會暴露無聊。

+0

滴答之間的時間間隔是多少?您可以嘗試在調用LoadData()之前禁用定時器,並在加載完成後重新啓用定時器。 – ebutusov 2012-03-06 22:55:53

+0

通常1秒,但它並不重要:我嘗試了5,10和20 - 並且仍然沒有快樂。數據檢索在0.02秒內完成。還嘗試在dvGrid_Scroll事件期間禁用Timer - 無效。最奇怪的是,即使是斷點也不會被打 - 所以它實際上從來沒有開火!但是,一個Timer如何知道並且關心我設置這個ScrollingRowIdx - 我到目前爲止還不知道.. – Astrogator 2012-03-06 23:16:33

+0

爲什麼它值得我試過你的例子,並且不能複製這個問題。一個區別是我使用的是對象的BindingList作爲數據源並向它添加行,但這不應該有所作爲。你是否嘗試過加載數據以確保在那裏沒有什麼奇怪的事情發生?你有沒有檢查,看看你的IDE沒有隱藏任何異常? – 2012-03-06 23:26:58

回答

1

這大概應該是一個評論,但我沒有足夠的信譽分置評所以...

你已經把一個斷點oTimer.Start()?第一次調用frmMain_Load()中的LoadData()是否完成?你的連接是否打開?也許有這以某種方式被吞噬,正如大衛音樂廳提到的例外?

1

EDIT2:嗯,我終於找到了根本原因:與2號線啓用oTimer.Start()不會被調用。原因是在第一次調用LoadData()[來自frmMain_Load(..)]時,第2行產生一個異常(,因爲該索引的初始值爲-1,這是一個無效值,將被分配回 )!正確的方式來保持滾動位置將改變2號線這樣的:

if( iRow >= 0 ) dgView.FirstDisplayedScrollingRowIndex=  iRow; 

但是討厭的事情是,不添加一個明確的try-catch塊LoadData()我不會找到它!在表單初始化/加載期間看起來像任何異常正在悄悄吞噬!!經驗教訓;但恕我直言,這不是一個好的方法,因爲我甚至不能依靠VS調試器來宣佈在WinForm的UI線程中可能發生的合理的高級異常。

答案代表去@appclay,我會把它交給@David Hall,因爲他是第一個暗示可能性的人。
謝謝大家!