简体   繁体   中英

Prevent databound DataGridView from sorting while editing

I have a databound DataGridView in a Win Forms app which the user may have sorted by a column. The problem is this: after the user leaves a row after editing a cell in the sorted column, the row is immediately re-sorted.

This is very disorienting for users and makes editing groups of rows together impossible.

The solution I'm looking for will effectively disable automatic re-sorting after an initial sort and then only sort again when the user requests it.

For the benefit of others, here is the solution I came up with, but I'd love to hear a better one.

I added an additional, non-persistent column to the DataTable called SORT_ORDER which is used only for sorting.

When the user clicks a column to sort, I copy the values and value type from the selected column to the SORT_ORDER column and then sort on SORT_ORDER. Since the SORT_ORDER is not visible and can't be edited, the sort order does not change even if the user edits the selected column. The event handler looks like this:

    private void MyDataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
        dirtyCellListenerEnabled = false;

        SORT_ORDER.ValueType = MyDataGridView.Columns[e.ColumnIndex].ValueType;

        foreach(DataGridViewRow r in MyDataGridView.Rows) {
            r.Cells[SORT_ORDER.Index].Value = r.Cells[e.ColumnIndex].Value;
        }

        switch(MyDataGridView.SortOrder) {
            case System.Windows.Forms.SortOrder.None:
                MyDataGridView.Sort(SORT_ORDER, ListSortDirection.Ascending);
                break;
            case System.Windows.Forms.SortOrder.Ascending:
                MyDataGridView.Sort(SORT_ORDER, ListSortDirection.Descending);
                break;
            case System.Windows.Forms.SortOrder.Descending:
                MyDataGridView.Sort(SORT_ORDER, ListSortDirection.Ascending);
                break;
        }
        dirtyCellListenerEnabled = true;
    }

Note that I had to disable and re-enable my cell listener so that my code doesn't treat the sort column update as a real change.

Before arriving at this solution, I had also tried adding the sort column to the DataGridView, but it doesn't work because the DataGridView can't sort on a column that doesn't exist in its data source.

I'm sure there are some other tweaks I could do, too, like suspending updates while populating the SORT_ORDER and displaying the sort glyph on the selected column.

This is a real pain as i'm finding out right now. Grids are brutally complicated sometimes for seemingly nothing

for each selected cell, I store the primary key, and the name of the grid column (i made a tiny class to hold those).

Then I throw them all into a list and iterate through them for the updating. Each time I update a cell value, i search for where the actual cell is now and replace my local reference variable to that cell so I can keep going in the code.

       Cell.Value = ValueToWrite
       Cell = FindCell(Cell.OwningRow.DataGridView, DataRow, ColName)

Function FindCell(Grid As DataGridView, DataRow As DataRow, ColName As String) As DataGridViewCell
    'Find the same cell, wherever you may be now, damn you sort.
    Dim GridRow = (From x As DataGridViewRow In Grid.Rows Where x.DataBoundItem.row Is DataRow).FirstOrDefault
    Dim Cell = GridRow.Cells(ColName)
    Return Cell
End Function

I've encountered this problem and couldn't get a decent answer, so I tried this and it worked,

    private void SortBoundDG()
    {
        DataTable TempTable;
        TempTable = (DataTable)DG.DataSource;
        TempTable.DefaultView.Sort =  ColumnName + " " + "DESC";
        DG.DataSource = TempTable.DefaultView.ToTable();
    }

simply convert the defaultview back to a table and set it as a source to your datagridview

Sounds like your GridView is data binding all over again. This means that your sort order will be lost. Enable the Viewstate of your gridview and make sure that you aren't binding the grid on postback.

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