Dynamic Scrolling of DataGridView Scrollbar

| August 11, 2010 | 1 Comment

Allow me to share little story with you guys. I used to answer questions on forums dedicated for .NET. Some of them are CodeProject, DotNetSpider, Experts Exchange. So there was a question that if we add some data either from database or manually from code the scroll bar position in DataGridView remains static i.e. it doesn’t show any response of dynamic addition of data (as shown in figure below).

Static scrollbar

Static scrollbar

And he was wishing for dynamic scrolling of scrollbar with addition of data ( as shown in figure below).

Dynamic Scrollbar

But later on he said that he miss communicated the requirements. He wanted something as (shown in figure below)

Rows static with scrollbar down

Rows static with scrollbar down

After researching all the properties of DataGridView I found a property FirstDisplayedScrollingRowIndex. This property sets or gets the index of the row that is the first row displayed in DataGridView. I use this property for solving my problem. And it solve it simply. And for solving the last diagram problem I used other code. Check that in code.

Concepts Covered

  1. Dynamic scrolling of scroll bar of DataGridView with addition of data in DataGridView.
  2. Refreshing DataGridView with addition of each row.

Code Snippet

There are two main controls on Form: Button named btnGet and DataGridView named dataGridView1. As soon the button is clicked we are adding data to DataGridView as well as refreshing the DataGridView. And also applying layout to all controls of DataGridView. Check the code for more.

Form1.cs (Last rows with Scrollbar down)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;</pre>
namespace GridViewScrollBar
{
public partial class Form1 : Form
{
//Datatable to which datarows are added on seperate thread
DataTable dt;

// Declaring delegate
public delegate void RefreshDataGridViewEventHandler();

//Declaring event
RefreshDataGridViewEventHandler eRefreshDataGridView;

public Form1()
{
InitializeComponent();

dt = new DataTable();
dt.Columns.Add(new DataColumn("Name"));
dt.Columns.Add(new DataColumn("City"));

// Attaching event handler
eRefreshDataGridView += new RefreshDataGridViewEventHandler(RefreshData);

// Fire when new Row is added to DataGridView
dt.TableNewRow += new DataTableNewRowEventHandler(dt_TableNewRow);

dataGridView1.DataSource = dt;
}

void dt_TableNewRow(object sender, DataTableNewRowEventArgs e)
{
dataGridView1.Invoke(eRefreshDataGridView);
}

public void AddData()
{
for (int i = 0; i < 1000; i++)
{
DataRow dataRow = dt.NewRow();
dataRow["Name"] = "Name " + i;
dataRow["City"] = "City " + i;

dt.Rows.Add(dataRow);
}
}

private void RefreshData()
{
dataGridView1.Refresh();
dataGridView1.PerformLayout();

// Set dataGridView FirstRow index
dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count-1;
}

private void btnGetData_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(AddData));
thread.Start();
}
}
}

Form1.cs (Static rows with Scrollbar down)
It’s better to just change the code snippet in method RefreshData() instead of writing whole code again.

private void RefreshData()
{
  dataGridView1.Refresh();
  dataGridView1.PerformLayout();

// Set dataGridView FirstRow index
//dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count - 1;

foreach (Control control in this.dataGridView1.Controls)
{
if (control is VScrollBar)
{
VScrollBar vscroll = (VScrollBar)control;
if (vscroll.Visible)
vscroll.Value = vscroll.Maximum;
}
}
}

At last we were able to manage dynamic scrolling of datagrieview scrollbar.

Download Source Code

Category: .NET, Tips

Comments (1)

Trackback URL | Comments RSS Feed

  1. Anonymous says:

    To update DataTable from a different thread, the following works as well:
    ——————————–
    public delegate void updateDataTableDelegate(DataRow row);

    private void updateDataTable(DataRow dr)
    {
    if (gvLog.InvokeRequired)
    {
    updateDataTableDelegate del = new updateDataTableDelegate(updateDataTable);
    gvLog.Invoke(del, new object[] { dr });
    }
    else
    {
    dt.Rows.Add(dr);
    }
    }

    //code fragment – start thread
    Thread thread = new Thread(new ThreadStart(Poll));
    thread.Start();

    void Poll()
    {
    while (true)
    {
    Thread.Sleep(100);
    //…
    DataRow dr = dt.NewRow();
    //…
    updateDataTable(dr);
    }
    }

Leave a Reply

%d bloggers like this: