2

Disclaimer: My career has been in embedded software, and I've just recently gotten into desktop applications. The application I'm developing has a simulation that produces a sparse 2-D matrix that can be on the order of 3000x3000 elements. The sparse matrix object comes from a class we created in house. I have a requirement to display this sparse matrix in its expanded form to the user.

I initially expanded it into a DataTable and bound it to a DataGridView but had obstacles with the sum total of column FillWeights exceeding a limit. Even overcoming that, it takes several minutes of processing before anything is displayed in the table.

I came across the DataGridView's virtual mode. Virtual Mode seem very well suited for what I have, but there are still several issues:

  1. There doesn't seem to be a way to convey to the DataGridView the maximum number of rows and/or columns (for purposes of scaling the scroll bars). If I set .RowCount and/or .ColumnCount, the application hangs for 2 minutes for creating the columns.
  2. I lose column sorting in Virtual Mode. There seems to be some way to do it in the MSDN documentation, but it's not apparent.

This leads me to believe data in the GUI world isn't meant to be viewed in big unwieldy tables (specifically with thousands of columns), especially given that we've already got it in a sparse matrix form. I think I need to push back on the requirement.

What would you do in my situation?

Community
  • 1
  • 1
  • I would first determine why it is taking so long. If you are querying a database the time is not coming from displaying the data in the DGV but from the time to get the data from the database. I have use a DGV to display almost a 1,000,000 rows from a database, but it does take time to extract the data from the database. You are saying the issue is TIME and then going a blaming the issue on the displaying. Please make up your mind what is the real issue!!! – jdweng Sep 09 '16 at 04:55
  • As I said in the initial write-up, the data is in a local data structure in local memory. There's no network or database latency to consider. The simple act of setting the .RowCount and .ColumnCount count to 3000 requires several minutes of processing before anything is displayed. I'll tighten up the language in the OP so as not to confuse you. – David Faulk Sep 09 '16 at 14:19
  • You should either write your own DataGrid or look for a third party to display large number of _columns_. – Alexander Petrov Sep 09 '16 at 17:47

1 Answers1

0

Setting RowCount can take a long time if there are any columns whose AutoSizeMode is set to something other than None. If you need other settings, you could temporarily set them to none, then set RowCount, then set them to what you really wanted.

As for column sorting, you have to roll your own, but I found this easier than expected. You need a couple of fields recording which column (index) is currently sorted, and in which direction:

private int _currentSortedColumnIndex = -1; // No sorting at first
private SortOrder _sortOrder = SortOrder.None;

Then you need to set an event handler for ColumnHeaderMouseClick:

myDataGridView.ColumnHeaderMouseClick += MyDataGridView_ColumnHeaderMouseClick;

The event handler itself configures the sorted column to have the correct sort-glyph, and triggers a sort on your source data:

private void MyDataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (_currentSortedColumnIndex >= 0 && _currentSortedColumnIndex < myDataGridView.ColumnCount)
        mysDataGridView.Columns[_currentSortedColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.None;

    if (_currentSortedColumnIndex == e.ColumnIndex)
        _sortOrder = _sortOrder == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
    else
    {
        _currentSortedColumnIndex = e.ColumnIndex;
        _sortOrder = SortOrder.Ascending;
    }

    mysDataGridView.Columns[_currentSortedColumnIndex].HeaderCell.SortGlyphDirection = _sortOrder;

    SortRecords(_currentSortedColumnIndex, _sortOrder);
    RefreshGrid();
}

SortRecords() is where you prepare your data cache so that your CellValueNeeded event handler can feed the cells in the new sort order, which is stored in _currentSortedColumnIndex and _sortOrder.

RefreshGrid() is where you basically clear the grid so that it will start firing CellValueNeeded events.

Morris
  • 126
  • 1
  • 10