2

我将 a 绑定DataTableDataSourcea 的DataGridView。我为所有人启用了该SortMode属性。但是,当我在 DataGridView 上进行排序时,排序更改并未反映在底层 DataSource 中,即 DataTable。 例如:AutomaticDataGridViewColumn

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 的行Alex, 27

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

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

4

5 回答 5

7

首先,即使您将DataTable对象绑定到 ,也会将其分离,也就是说,如果您更改您的,它不会影响您的. 在您的情况下,您希望将排序反映在. 因此,您需要在每次. 因此,您需要捕获.DataGridViewDataSourceDataGridViewDataTableDataGridViewDataTableDataGridViewColumnHeaderMouseClickDataGridView

另一个重要的事情是,在实现两者的同步排序中DataTableDataGridView是具有属性的类的DefaultView方法。所以,我们要做的是每次更改排序时,我们也会排序。DatableSortDataGridViewDataTable

首先,我们需要使 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.
  }

您现在可以使用 table 对象并根据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);
  }
于 2013-10-31T06:18:07.883 回答
3

您可以将您DataTable放入BindingSource容器并将此类设置为DataGridView.

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

要了解BindingSort,请参阅此链接

于 2013-10-30T12:52:10.453 回答
2

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

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

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

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

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

于 2017-03-01T22:18:54.853 回答
2

老问题,但仍然没有提到简单的解决方案,所以我在这里发布给现在寻找答案的人:

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

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

于 2019-06-26T00:59:22.107 回答
0

我找到了另一种替代解决方案,我从中获取唯一列的值,DataGridView然后查询底层 DataSourceDataTable以获取行,即使DataTable未排序也是如此。
但我想知道如何排序DataTable解决方案

于 2013-10-31T09:51:33.950 回答