【问题标题】:Datasource not reflecting sorting in DataGridView数据源不反映 DataGridView 中的排序
【发布时间】:2013-11-10 00:12:18
【问题描述】:

我将DataTable 绑定为DataSourceDataGridView。我为所有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 索引处的行即使在排序后也是Alex, 27

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

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

【问题讨论】:

  • 排序只是在 UI 中进行。为什么要对底层数据源进行排序?您的数据源只保存您的数据,如果您想按特定顺序访问它,您可以为此使用索引或视图,当然最终用户认为排序可能不会很有趣。
  • Gridview排序时为什么要排序反映在数据表中?
  • 可以在后面的代码中对数据源进行排序。
  • 请在数据表绑定到 DataGridView 之前显示一些代码,特别是您的查询。
  • 如果你可以选择我真的会推荐 WPF,在这种事情上它会更好。

标签: c# winforms sorting datagridview datatable


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    要了解BindingSort,请参阅此link

    【讨论】:

    • 所以,只需将我的 DataTable 包装到 BindingSource 即可启用从 DataGridViewDataTable 的排序? BindingSortbtw 是什么?
    • 我确实像你说的那样。数据表上仍然没有自动排序。
    • 是的,但如果您更改 DataGridView 排序顺序,BindingSource 会反映此更改...
    【解决方案3】:

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

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • @Md.Ibrahim 检查我上面的答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-04
        • 2016-12-05
        • 2017-12-11
        • 2017-12-29
        相关资源
        最近更新 更多