数据源不反映DataGridView中的排序

时间:2013-10-30 12:13:34

标签: c# winforms sorting datagridview datatable

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

DataGridViewColumn


现在,如果我要获得如下所示的选定行,它将始终返回DataTable 中的0 Index处的行,即使在排序后也是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;

Alex, 27

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

5 个答案:

答案 0 :(得分:5)

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

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

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

DataTable table;

其次,我们需要初始化ColumnHeaderMouseClick的事件监听器,出于实际目的,我们将其设置为Form构造函数。

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

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

 void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
 {            

 }

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

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

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);
  }

答案 1 :(得分:3)

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

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

要了解BindingSort,请参阅此link

答案 2 :(得分:1)

其他人和我一样来到这里。

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

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

而不是DataRow row = dataTable.Rows[0];

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

答案 3 :(得分:1)

旧问题,但仍未提及简单的解决方案,因此,我将其发布在此处,供当今寻求答案的人们使用:

DataRow row = ((DataRowView)yourDataGridView.SelectedRows[0].DataBoundItem).Row;
int index = yourDataTable.Rows.IndexOf(row);

index将是您的DataTable中该行的索引,与DataGridView中的选定行相对应,但是您已经对其进行了排序。

答案 4 :(得分:0)

我找到了另一种替代解决方案,我从DataGridView获取了一个唯一列的值,然后查询基础DataSource DataTable以获取行,即使DataTable未排序。
但我想知道如何对DataTable进行排序。 Solution