简体   繁体   中英

C# - Datagridview update

My application requires a datagridview to be regularly automatically updated with data from a database to reflect changes in the system, which is not a problem.

My issue is that when the datagridview is updated it freezes the UI briefly and prevents scrolling. So I can think of two possible solutions:

To pause the updates when a UI event is active - though I don't know what a global user event would be?

Or use a background worker to update the datagridview - though I don't know how you would update the UI from a background worker?

using (SqlDataAdapter a = new SqlDataAdapter("SELECT Name,Value FROM dbo.IOData", c))
{
  DataTable IOProcData = new DataTable();
  // Populate data table
  a.Fill(IOProcData);
  // Record displayed row
  int temp = dataGridView1.FirstDisplayedScrollingRowIndex;
  IOBinding.DataSource = IOProcData;
  // Reset displayed row
  if (temp > 0)
  {
    dataGridView1.FirstDisplayedScrollingRowIndex = temp;
  }
}

EDIT:

Is there an event that triggers when a scrollbar of a datagridview is first clicked like mousedown but for the scrollbar? The scroll event happens after the scroll action so would be to late.

You can separate responsabilities. Your time consuming process probably is getting data from database, not assigning the datasource.

In your backgroundWorker you can fetch the information from database. When finished, simply assign the filled table to your gridview.

Here is an example:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        if (e.Error != null) {
            //Handle error
        } else {
            IOBinding.DataSource = (DataTable)e.Result;
        }
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
    using (SqlDataAdapter a = new SqlDataAdapter("SELECT Name,Value FROM dbo.IOData", c)) {
        DataTable IOProcData = new DataTable();
        // Populate data table
        a.Fill(IOProcData);
        // Record displayed row
        e.Result = a;
    }
}

You can init a Timer thread that responsible for fetching new data and update your DataGrid

internal void InitTimer()
    {
        _timer = new Timer();
        _timer.Tick += (sender, args) => BindDataGrid();
        _timer.Interval = 1000;
        _timer.Start();
        _timerStart = true;
    }

About scrolling issue, i faced another problem before that after update the selectedRow become 0. I solved this problem by Binding DataTable to DataGrid and Merge two results together.

  var newData = // your data as DataTable Format;

  // Get Current Scroll position
  var scrollingRowIndex = MyDataGridView.FirstDisplayedScrollingRowIndex;

  // Get Current Row
  var currentRow = MyDataGridView.CurrentCell != null
                                 ? MyDataGridView.CurrentCell.RowIndex
                                 : -1;

  DataTable bindedData;
  var currentDataSource = MyDataGridView.DataSource as DataTable;


  if (currentDataSource != null)
  {
       currentDataSource.Merge(newData);
       bindedData = currentDataSource;
  }
  else
  {
      bindedData = newData;
  }

  MyDataGridView.DataSource = bindedData;
  MyDataGridView.Update();

  // set Current Scroll position
  if (scrollingRowIndex > -1)
         MyDataGridView.FirstDisplayedScrollingRowIndex = scrollingRowIndex;

  // set Current Row
  if (currentRow > -1)
         MyDataGridView.Rows[currentRow].Selected = true;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM