1

I apologize in advance if my question is hard to understand because of my broken English.

In my Windows Form Application in C#, I have a DataGridView control that keeps showing the most recent table data. With a Timer control, it automatically refreshes the table in the DataGridView. Since there are more columns than the DataGridView can show at once, there is a horizontal scrollbar.

I am also using FirstDisplayedScrollingColumnIndex to get the current scroll position. This way, when the user is browsing the Table with the scrollbar and the table refresh occurs, the scrollbar can stay where it was before the refresh.

However, there is one problem. Since FirstDisplayedScrollingColumnIndex can only store an integer value, when the table's leftmost column within the view is not fully shown, it snaps back upon table refresh, so that the leftmost column within the view becomes fully shown. This becomes an issue when the user is browsing the rightmost column with the scrollbar because upon refresh, it snaps back to display the leftmost column, instead of the rightmost one, that is, the scrollbar does not stay at the rightmost position.

Here is the picture. This is what it should keep showing upon table refresh: enter image description here

As you can see, Sex column is fully shown but the leftmost column is halfway shown. When the table refresh occurs, it snaps one column back to show the leftmost column within the view. This prevents the user from viewing the Sex column's data when the refresh occurs. (Picture below) I think this is because FirstDisplayedScrollingColumnIndex stores an integer value, the column position.

enter image description here

private int scrollPositionColumn;
private void Timer_Tick(object sender, EventArgs e){
    //Before the update, save the current scrollbar position
    if(MyDGV.FirstDisplayedScrollingColumnIndex >= 0){
        scrollPositionColumn = MyDGV.FirstDisplayedScrollingColumnIndex;
    }
    UpdateGridView();
}

private void UpdateGridView(){
    /*Some code*/

    //Restore the previous position of the scrollbar
    MyDGV.FirstDisplayedScrollingColumnIndex = scrollPositionColumn;
    /*Some code*/
}

Can someone please give me advice on how to fix this issue?

Here is the simplified code that I have.

Mika Jones
  • 287
  • 1
  • 5
  • 13
  • Can you provide more info on `/* some code */` block? If you update cell-by-cell then you don't need to set `FirstDisplayedScrollingColumnIndex` because existing data are updated. – vasek Nov 01 '17 at 13:02
  • Instead of updating cell-by-cell, I refresh the whole table each time. – Mika Jones Nov 01 '17 at 13:07
  • 1
    You should not do that. It is slow and brings obvious unwanted scrollbar manipulation. You should provide internal cache and update only cells that have changed between two consecutive timer events. Using this approach you won't need any manipulation with `FirstDisplayedScrollingColumnIndex`. – vasek Nov 01 '17 at 13:09
  • That's very true. By internal cache, could I use a 2-D array or something to temporary store the data before the update? – Mika Jones Nov 01 '17 at 13:17
  • 1
    That totally depends on your internal data structure and data retreival algorithm. Please provide full and reproducible example so that we can propose the best suitable solution. – vasek Nov 01 '17 at 13:18
  • Also what if there are many date update each time the refresh takes place? In the pictures I provided in my post, I am using a fake `DataGridView` data because it is convenient. In my actual application, I have a huge `DataGridView` control and data in many cells constantly change almost every second. – Mika Jones Nov 01 '17 at 13:18
  • 1
    It completely depends. Solutions vary from [virtualization](https://stackoverflow.com/questions/4649995/how-to-suspend-a-datagridview-while-updating-its-columns) to simple update of several cells with `SuspendLayout` and `ResumeLayout`. – vasek Nov 01 '17 at 13:27
  • Thank you, vesek, for the ideas! – Mika Jones Nov 01 '17 at 13:56

0 Answers0