数据源未反映数据网格视图中的排序

本文关键字:视图 排序 网格 数据网 数据 数据源 | 更新日期: 2023-09-27 18:37:24

我将DataTable绑定为DataGridViewDataSource。我启用了 SortMode 属性以Automatic所有DataGridViewColumn。但是,当我在 DataGridView 上进行排序时,排序更改不会反映在基础数据源(即数据表)中。
例如:

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[];

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

数据源未反映数据网格视图中的排序

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

另一个重要的事情是,在实现DataTableDataGridView的同步排序时,Datable具有Sort属性的类的DefaultView方法。因此,我们要做的是每次更改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,请参阅此链接。

老问题,但仍然没有提到简单的解决方案,所以我把它贴在这里,供现在寻找答案的人使用:

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

index将是数据表中与 DataGridView 中所选行对应的行的索引,但您对其进行了排序。

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

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

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

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

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

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