数据源未反映数据网格视图中的排序
本文关键字:视图 排序 网格 数据网 数据 数据源 | 更新日期: 2023-09-27 18:37:24
我将DataTable
绑定为DataGridView
的DataSource
。我启用了 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
中的排序/排序发生变化时捕获一个事件。因此,您需要在这方面抓住DataGridView
的ColumnHeaderMouseClick
事件。
另一个重要的事情是,在实现DataTable
和DataGridView
的同步排序时,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
进行排序。溶液