选择行WinForm应用程序排序的DataGridView时应用程序、WinForm、DataGridView

2023-09-03 02:37:35 作者:怎么办,我想你了!

在一个WinForm应用程序,C#4.0中,我必须绑定到一个SortableBindingList一个DataGridView。因此,它可以通过点击标题列进行排序 - 一切优秀到目前为止; - )

In a WinForm application, C# 4.0, I have a DataGridView bound to a SortableBindingList. Hence it can be sorted by clicking on the header column - all fine so far ;-)

的问题是,所选择的行似乎是记住的行号。这是发生了什么:

The problem is, that selected rows seem to be "remembered" by the row number. Here is what happens:

A*  <- "Selected"
B
C

现在在顶部,选择排序下降,C。我想有仍然选定的:

Now sorting descending, C on top and selected. I'd like to have still A selected:

C*  <- "Selected"
B
A   <- "Want have"

同样的情况,与被选择的多行类似。是否有解决方法吗?

Same happens similar with multiple rows being selected. Is there a workaround for this?

推荐答案

您可以通过排序,然后再把重新选择行之前存储离开当前选定的行(或列)的值解决此问题。

You can work around this behaviour by storing away the value of the currently selected row (or rows) before sorting and then reselecting the row afterwards.

您需要使用CellMouseDown事件 - 有必要使用此事件,因为它是唯一一个触发排序发生之前。像ColumnHeaderMouseClick替代的事件是一切都晚了。

You need to use the CellMouseDown event - it is necessary to use this event since it is the only one which fires before the sort happens. Alternative events like ColumnHeaderMouseClick are all too late.

在CellMouseDown事件处理程序检查该行索引为-1,以确保集流管被选定。

In the CellMouseDown eventhandler check that the row index is -1 to ensure that the headers were selected.

void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.RowIndex == -1)
    {
        selected = dataGridView1.SelectedRows[0].Cells[0].Value.ToString();
    }
}

我有一类级别字段选择,我用它来存储选定的列的唯一标识符。如果你没有一个唯一的ID,那么你可以添加一列中为此目的而将其隐藏。

I have a class level field selected that I use to store the unique identifier of the column that is selected. If you don't have a unique id then you could add in a column for this purpose and hide it.

然后在DataGridView中的排序事件处理程序,你可以使用网格的绑定源的.Find()方法:

Then in the Sorted eventhandler of the DataGridView you can use the .Find() method of the grid's binding source:

void dataGridView1_Sorted(object sender, EventArgs e)
{
    if (!string.IsNullOrEmpty(selected))
    {
        int itemFound = _bindingSource.Find("name", selected);
        _bindingSource.Position = itemFound;
    }
}

在调查这个我发现下面的post在MSDN论坛,答案使用DataBindingComplete事件 - 我不是100%,为什么他们发现,必要的,因为我的做法一直为我所有的测试,但你可能会觉得这是一个有益的参考。

While investigating this I found the following post on the MSDN forums where the answer uses the DataBindingComplete event - I'm not 100% why they found that necessary as my approach has worked for all my tests, but you might find it a helpful reference.