数据源不反映DataGridView中的排序

我将DataTable绑定为DataGridViewDataSource 。 我为所有DataGridViewColumn启用了SortMode属性为Automatic 。 但是当我在DataGridView上进行排序时,排序更改没有反映在基础DataSource中,即DataTable。
例如:

 DataTable table = new DataTable(); table.Columns.Add("Name"); table.Columns.Add("Age", typeof(int)); table.Rows.Add("Alex", 27); table.Rows.Add("Jack", 65); table.Rows.Add("Bill", 22); dataGridView1.DataSource = table; 

现在,如果我要获得如下所示的选定行,它将始终返回DataTable中0 Index处的行, 即使在排序后Alex, 27

 DataRow newRow = table.NewRow(); newRow.ItemArray = table.Rows[dataGridView1.Rows.IndexOf(dataGridView1.SelectedRows[0])].ItemArray.Clone() as object[]; 

有人可以建议我应该如何处理这种情况?

首先, DataTable对象与DataGridView分离,即使您将其绑定到DataSource ,也就是说,如果更改DataGridView ,它将不会影响您的DataTable 。 在您的情况下,您希望DataGridView的排序反映在DataTable 。 因此,每次DataGridView中的排序/排序发生变化时,您都需要捕获一个事件。 因此,您需要捕获DataGridViewColumnHeaderMouseClick事件。

另一个重要的事情是,在实现DataTableDataGridView的同步排序时, Datable类的DefaultView方法具有Sort属性。 所以,我们要做的是每次DataGridView改变排序时我们也会对DataTable排序。

首先,我们需要将DataTable对象设置为全局,以便我们以后可以在任何地方访问它。

 DataTable table; 

其次,我们需要为ColumnHeaderMouseClick初始化一个事件监听器,为了实际目的,我们将它设置在Form构造函数中。

 InitializeComponent(); dataGridView1.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler(dataGridView1_ColumnHeaderMouseClick); 

然后我们有这个空的鼠标事件处理程序:

  void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { } 

如果上述方法没有自动出现,只需复制并粘贴代码即可。

为了便于说明,我们将在Form Load期间添加DataTable ,在这种情况下,我将使用您自己的代码:

 table = new DataTable(); table.Columns.Add("Name"); table.Columns.Add("Age", typeof(int)); table.Rows.Add("Alex", 27); table.Rows.Add("Jack", 65); table.Rows.Add("Bill", 22); dataGridView1.DataSource = table; 

最后我们将在ColumnHeaderMouseClick事件中放入一些代码:

  void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { if (dataGridView1.SortOrder.ToString() == "Descending") // Check if sorting is Descending { table.DefaultView.Sort = dataGridView1.SortedColumn.Name + " DESC"; // Get Sorted Column name and sort it in Descending order } else { table.DefaultView.Sort = dataGridView1.SortedColumn.Name + " ASC"; // Otherwise sort it in Ascending order } table = table.DefaultView.ToTable(); // The Sorted View converted to DataTable and then assigned to table object. } 

您现在可以使用表对象并根据DataGridView的排序顺序进行排序。

为了确认我的声明,我们将在您的表单中创建一个名为button1的按钮,单击它时将显示第一行和已排序的列值,如:

  private void button1_Click(object sender, EventArgs e) { String sortedValue = dataGridView1.SortedColumn.Name == "Name" : table.Rows[0][0].ToString() ? table.Rows[0][1].ToString(); MessageBox.Show(sortedValue); } 

您可以将DataTable放入BindingSource容器中,并将此类设置为DataGridView数据源。

 BindingSource bindingSource1 = new BindingSource(); bindingSource1.DataSource = dataTable; dataGridView1.DataSource = bindingSource1; // another grid view options... 

要了解BindingSort ,请参阅此链接 。

对于其他人来这里的原因和我一样。

我无法将基础数据排序,因此当我删除一行时,它删除了错误的一行。

我发现DataTable不会被排序,只有DataTable.DefaultView会被排序。

所以代替DataRow row = dataTable.Rows[0];

你会做DataRow row = dataTable.DefaultView[0].Row;

我发现了另一种替代解决方案,我从DataGridView获取一个唯一列的值,然后查询底层DataSource DataTable以获取行,即使DataTable没有排序。
但我想知道如何对DataTable进行排序。 解