none
請教 DataGridView 捲軸問題 RRS feed

  • 問題

  • 各位好,

    我的環境是 Visual Studio 2008

    在一個有專案中遇到 DataGridView 捲軸顯示不正常的問題,
    為釐清、測試, 重開一個新的 Windows Form 專案,
    其中各放一個 DataGridView 和 Button,
    測試程式如下:

        Dim DTable As DataTable
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            LoadData()
        End Sub
    
        Private Sub LoadData()
            Dim PreFstRowInd As Integer
            Dim PreFstColInd As Integer
    
            '載入資料前記下顯示位置
            PreFstRowInd = DataGridView1.FirstDisplayedScrollingRowIndex
            PreFstColInd = DataGridView1.FirstDisplayedScrollingColumnIndex
    
            '<模擬>載入資料
            DataGridView1.DataSource = Nothing
            If DTable IsNot Nothing Then
                DTable.Dispose()
                DTable = Nothing
            End If
            DTable = New DataTable
    
            For i = 1 To 20
                DTable.Columns.Add(i.ToString)
            Next
    
            For i = 1 To 20
                Dim EnuData(19) As Object
                For c = 0 To 19
                    EnuData(c) = i
                Next
                DTable.Rows.Add(EnuData)
            Next
    
            DataGridView1.DataSource = DTable
    
            '還原顯示位置
            If PreFstRowInd >= 0 Then
                DataGridView1.FirstDisplayedScrollingRowIndex = PreFstRowInd
            End If
            If PreFstColInd >= 0 Then
                DataGridView1.FirstDisplayedScrollingColumnIndex = PreFstColInd
            End If
    
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            '<模擬>使用者移動捲軸
            DataGridView1.FirstDisplayedScrollingRowIndex = 18
            DataGridView1.FirstDisplayedScrollingColumnIndex = 18
    
            DataGridView1.Enabled = False
    
            '真正的載入資料有其他耗時運算程序
            '其中包含 Application.DoEvents 
            '所以前面先 DataGridView1.Enabled = False
    
            '<模擬>載入資料
            LoadData()
    
            DataGridView1.Enabled = True
    
            '發現捲軸位置不正常, 測試下列方法無改善
            DataGridView1.Invalidate()
            DataGridView1.Update()
    
        End Sub
    

    按下 Button1 後如下圖:

    明明不是在第一行第一列, 捲軸位置卻在最上/最左?

    經測試, 只要將 DataGridView1.Enabled = False 拿掉就會正常,
    但是我實際過程中有些耗時運算, 不希望使用者對 DataGridView1 做任何動作.

    請問如何在保持 DataGridView1.Enabled = False 的情況下,
    能讓捲軸正常顯示?

    謝謝!

    2014年3月12日 上午 07:45

解答

  • 您好,

    如果不希望改的話,是否使用 DataGridView1.Readonly 屬性呢?


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已標示為解答 Ader.Chen 2014年3月16日 下午 01:37
    2014年3月14日 上午 08:01
  • 意外試出解決方法了

    原來只要將設定 FirstDisplayedScrollingRowIndex, FirstDisplayedScrollingColumnIndex 的程式由 DataGridView1.Enabled 之前改移到之後就沒問題了:

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            '<模擬>使用者移動捲軸
            DataGridView1.FirstDisplayedScrollingRowIndex = 18
            DataGridView1.FirstDisplayedScrollingColumnIndex = 18
    
            DataGridView1.Enabled = False
    
            '<模擬>載入資料
            LoadData()
    
            DataGridView1.Enabled = True
    
            '下面兩行模擬還原位置的程式原在 Sub LoadData() 內, 會有捲軸不正常狀況
            '改移到 DataGridView1.Enabled = True 之後, 捲軸位置就正常了!
            DataGridView1.FirstDisplayedScrollingRowIndex = 18
            DataGridView1.FirstDisplayedScrollingColumnIndex = 18
    
        End Sub
    仍謝謝兩位前輩熱心提供資訊!

    • 已標示為解答 Ader.Chen 2014年3月16日 下午 01:37
    2014年3月14日 下午 03:50

所有回覆

  • 您好,

    如果不希望改的話,是否使用 DataGridView1.Readonly 屬性呢?


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已標示為解答 Ader.Chen 2014年3月16日 下午 01:37
    2014年3月14日 上午 08:01
  • 謝謝您的回覆,

    一方面有其他的機制在判斷/切換 ReadOnly 屬性, 希望與 Enabled 使用時機切割開來,

    一方面在運算過程中也不希望使用者捲動/改變 CurrentCell, 這就不適合用 ReadOnly 屬性來檔...

    真不得已的話, 可能不用 DataGridView 的捲軸, 改用 HScrollBar、VScrollBar, 還在 Try...

    謝謝!

    2014年3月14日 上午 08:47
  • 您好,

    請試一下,DataGridView的PerformLayout

    DataGridView1.PerformLayout()


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2014年3月14日 上午 10:24
  • 在 Form_Load 試試

    加這行

    Dim tmpPtr As IntPtr = DataGridView1.Handle

    若有用,可以看看這邊的文章:

    [VB2005] ListView 初始化與 ItemChecked 事件

    [bug]在對話盒中動態建立 DateTimePicker 類別在設定 Value 屬性後 Text 屬性會不正常


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年3月14日 下午 01:27
  • 亂馬客 前輩您好,

    試過在 LoadData() 之後加 DataGridView1.PerformLayout(), 有點變化:
    垂直捲軸的有正常顯示到相對位置了!
    但水平捲軸仍在最左邊位置, 不是正常相對位置!?

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            '<模擬>使用者移動捲軸
            DataGridView1.FirstDisplayedScrollingRowIndex = 18
            DataGridView1.FirstDisplayedScrollingColumnIndex = 18
    
            DataGridView1.Enabled = False
    
            '真正的載入資料有其他耗時運算程序
            '其中包含 Application.DoEvents 
            '所以前面先 DataGridView1.Enabled = False
    
            '<模擬>載入資料
            LoadData()
    
            DataGridView1.Enabled = True
    
            DataGridView1.PerformLayout()
            '垂直捲軸有顯示到正常相對位置了,
            '但水平位置仍不正確, 此例的 FirstDisplayedCell.ColumnIndex=18, 但捲軸位置仍在最左邊!?
            Me.Text = DataGridView1.FirstDisplayedCell.ColumnIndex
    
        End Sub
    

    2014年3月14日 下午 03:04
  • 心冷熱情熄 前輩您好,

    試過在 Form1_Load 內第一行加
    Dim tmpPtr As IntPtr = DataGridView1.Handle

    不過對此問題無影響, 應該是適用於不同狀況,
    此問題狀況是:
    1. 當使用者移動到 DataGridView 某個位置 (水平/垂直捲軸已不在最左/上)
    2. 記下顯示位置 (FirstDisplayedScrollingRowIndex, FirstDisplayedScrollingColumnIndex)
    3. DataGridView1.Enabled = False
    4. 載入來源資料 (更新 DataGridView1.DataSource)
    5. DataGridView1.Enabled = True
    6. 還原顯示位置 (FirstDisplayedScrollingRowIndex, FirstDisplayedScrollingColumnIndex)
    此時雖然 DataGridView 的確有移到原顯示位置,
    但捲軸不在相對位置, 而仍在最左/上端!?

    依 亂馬客 前輩建議, 在最後 DataGridView1.PerformLayout 的話,
    垂直捲軸的有正常顯示到相對位置了,
    但水平捲軸仍在最左邊位置, 不是正常相對位置.

    已知若不異動 DataGridView1.DataSource 或 .Enabled 的話就不會發生此狀況,
    偏偏兩者在此專案都是必要的...
    2014年3月14日 下午 03:24
  • 意外試出解決方法了

    原來只要將設定 FirstDisplayedScrollingRowIndex, FirstDisplayedScrollingColumnIndex 的程式由 DataGridView1.Enabled 之前改移到之後就沒問題了:

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            '<模擬>使用者移動捲軸
            DataGridView1.FirstDisplayedScrollingRowIndex = 18
            DataGridView1.FirstDisplayedScrollingColumnIndex = 18
    
            DataGridView1.Enabled = False
    
            '<模擬>載入資料
            LoadData()
    
            DataGridView1.Enabled = True
    
            '下面兩行模擬還原位置的程式原在 Sub LoadData() 內, 會有捲軸不正常狀況
            '改移到 DataGridView1.Enabled = True 之後, 捲軸位置就正常了!
            DataGridView1.FirstDisplayedScrollingRowIndex = 18
            DataGridView1.FirstDisplayedScrollingColumnIndex = 18
    
        End Sub
    仍謝謝兩位前輩熱心提供資訊!

    • 已標示為解答 Ader.Chen 2014年3月16日 下午 01:37
    2014年3月14日 下午 03:50