单击按钮时,我需要在 datagridview 中向上或向下移动所选行,但 datagridview 绑定到 sql 数据库。起初我使用了这段代码,但是发生了错误,因为如果控件绑定到数据,则无法以编程方式将行添加到 datagridview 集合中。是否可以通过datagridview组织数据库中行的移动?
private void btnUp_Click(object sender, EventArgs e)
{
DataGridView dgv = gridTasks;
try
{
int totalRows = dgv.Rows.Count;
// get index of the row for the selected cell
int rowIndex = dgv.SelectedCells[ 0 ].OwningRow.Index;
if ( rowIndex == 0 )
return;
// get index of the column for the selected cell
int colIndex = dgv.SelectedCells[ 0 ].OwningColumn.Index;
DataGridViewRow selectedRow = dgv.Rows[ rowIndex ];
dgv.Rows.Remove( selectedRow );
dgv.Rows.Insert( rowIndex - 1, selectedRow );
dgv.ClearSelection();
dgv.Rows[ rowIndex - 1 ].Cells[ colIndex ].Selected = true;
}
catch { }
}
private void btnUp_Click(object sender, EventArgs e)
{
DataGridView dgv = gridTasks;
try
{
int totalRows = dgv.Rows.Count;
// get index of the row for the selected cell
int rowIndex = dgv.SelectedCells[ 0 ].OwningRow.Index;
if ( rowIndex == 0 )
return;
// get index of the column for the selected cell
int colIndex = dgv.SelectedCells[ 0 ].OwningColumn.Index;
DataGridViewRow selectedRow = dgv.Rows[ rowIndex ];
dgv.Rows.Remove( selectedRow );
dgv.Rows.Insert( rowIndex - 1, selectedRow );
dgv.ClearSelection();
dgv.Rows[ rowIndex - 1 ].Cells[ colIndex ].Selected = true;
}
catch { }
}
如果绑定到 SQL 数据库意味着 DataGridView.DataSource 是 DataTable,则考虑使用 BindingSource。
创建表单级 BindingSource 变量,获取 DataTable 并将 BindingSource.DataSource 分配给您的表。
将以下类添加到您的项目中,该类负责通过 BindingSource 向上/向下移动行。
笔记,
在代码中,如果设置了排序顺序,则需要将其删除,这在下面的代码中完成。
要编辑单元格,请双击或 F2。
public static class BindingSourceExtensions
{
/// <summary>
/// Move row up by one
/// </summary>
/// <param name="sender"></param>
public static void MoveRowUp(this BindingSource sender)
{
if (!string.IsNullOrWhiteSpace(sender.Sort))
{
sender.Sort = "";
}
var newIndex = Convert.ToInt32((sender.Position == 0) ?
0 :
sender.Position - 1);
var dt = (DataTable)sender.DataSource;
DataRow rowToMove = ((DataRowView)sender.Current).Row;
var newRow = dt.NewRow();
newRow.ItemArray = rowToMove.ItemArray;
dt.Rows.RemoveAt(sender.Position);
dt.Rows.InsertAt(newRow, newIndex);
dt.AcceptChanges();
sender.Position = newIndex;
}
/// <summary>
/// Move row down by one
/// </summary>
/// <param name="sender"></param>
public static void MoveRowDown(this BindingSource sender)
{
if (!string.IsNullOrWhiteSpace(sender.Sort))
{
sender.Sort = "";
}
var upperLimit = sender.Count - 1;
var newIndex = Convert.ToInt32((sender.Position + 1 >= upperLimit) ?
upperLimit :
sender.Position + 1);
var dt = (DataTable)sender.DataSource;
DataRow rowToMove = ((DataRowView)sender.Current).Row;
var newRow = dt.NewRow();
newRow.ItemArray = rowToMove.ItemArray;
dt.Rows.RemoveAt(sender.Position);
dt.Rows.InsertAt(newRow, newIndex);
dt.AcceptChanges();
sender.Position = newIndex;
}
}
在您的表单中,用于向上/向下按钮。
private void upButton_Click(object sender, EventArgs e)
{
_bindingSource.MoveRowUp();
}
private void downButton_Click(object sender, EventArgs e)
{
_bindingSource.MoveRowDown();
}
我所做的是将 DataGridView.SelectionMode 设置为 FullRowSelect,因为如果没有此设置,则在向上/向下移动行时,当前单元格将移动到第一个单元格,这对用户来说可能看起来很奇怪。
注意:要通过单击按钮获取当前行数据。
var row = ((DataRowView)_bindingSource.Current).Row;
在下面的 gif 中,前两列通常不会显示,它们仅用于演示目的。我使用第一列将订单保存到数据库表中以保留订单。