DataGridView选定的行向上和向下移动

如何允许向上或向下移动DataGridView(DGV)中的选定行。 我之前用ListView完成了这个。 不幸的是,对我来说,更换DGV不是一种选择( 诅咒 )。 顺便说一句,DGV数据源是一个通用集合。

DGV侧面有两个按钮,是,UP和Down。 任何人都可以帮我指出正确的方向。 我确实有我用于ListView的代码,如果它有帮助(它没有帮助我)。

如果您以编程方式更改集合中项目的顺序,则DGV应自动反映该项目。

邋,,半工作的例子:

List foo = DGV.DataSource; int idx = DGV.SelectedRows[0].Index; int value = foo[idx]; foo.Remove(value); foo.InsertAt(idx+1, value) 

其中一些逻辑可能是错误的,这可能也不是最有效的方法。 此外,它没有考虑多行选择。

嗯,最后一件事,如果你使用标准的List或Collection,这将不会顺利进行。 列表和集合on’t发出DGV发现对数据绑定有用的事件。 每次更改集合时都可以“打嗝”数据绑定,但更好的解决方案是使用System.ComponentModel.BindingList。 当您更改BindingList的顺序时,DGV应自动反映更改。

只是为了扩展Yoopergeek的答案,这就是我所拥有的。 我没有使用DataSource(数据在表单关闭时被删除到注册表,并在表单加载时重新加载)

此示例将阻止行离开网格并丢失,并重新选择此人所在的单元格。

为了简化复制/粘贴,我进行了修改,因此您只需要将“gridTasks”更改为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 btnDown_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 == totalRows - 1 ) 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 { } } 

这应该工作。 我使用BindingSource而不是将我的List直接绑定到DataGridView:

  private List items = new List { new MyItem {Id = 0, Name = "Hello"}, new MyItem {Id = 1, Name = "World"}, new MyItem {Id = 2, Name = "Foo"}, new MyItem {Id = 3, Name = "Bar"}, new MyItem {Id = 4, Name = "Scott"}, new MyItem {Id = 5, Name = "Tiger"}, }; private BindingSource bs; private void Form1_Load(object sender, EventArgs e) { bs = new BindingSource(items, string.Empty); dataGridView1.DataSource = bs; } private void button1_Click(object sender, EventArgs e) { if (bs.Count <= 1) return; // one or zero elements int position = bs.Position; if (position <= 0) return; // already at top bs.RaiseListChangedEvents = false; MyItem current = (MyItem)bs.Current; bs.Remove(current); position--; bs.Insert(position, current); bs.Position = position; bs.RaiseListChangedEvents = true; bs.ResetBindings(false); } private void button2_Click(object sender, EventArgs e) { if (bs.Count <= 1) return; // one or zero elements int position = bs.Position; if (position == bs.Count - 1) return; // already at bottom bs.RaiseListChangedEvents = false; MyItem current = (MyItem)bs.Current; bs.Remove(current); position++; bs.Insert(position, current); bs.Position = position; bs.RaiseListChangedEvents = true; bs.ResetBindings(false); } public class MyItem { public int Id { get; set; } public String Name { get; set; } } 

首先填充datagridview,例如你有3个列的表

 DataTable table = new DataTable(); table.Columns.Add("col1"); table.Columns.Add("col2"); table.Columns.Add("col3"); foreach (var i in yourTablesource(db,list,etc)) { table.Rows.Add(i.col1, i.col2, i.col2); } datagridview1.DataSource = table; 

然后,按下按钮单击

 int rowIndex; private void btnUp_Click(object sender, EventArgs e) { rowIndex = datagridview1.SelectedCells[0].OwningRow.Index; DataRow row = table.NewRow(); row[0] = datagridview1.Rows[rowIndex].Cells[0].Value.ToString(); row[1] = datagridview1.Rows[rowIndex].Cells[1].Value.ToString(); row[2] = datagridview1.Rows[rowIndex].Cells[2].Value.ToString(); if (rowIndex > 0) { table.Rows.RemoveAt(rowIndex); table.Rows.InsertAt(row, rowIndex - 1); datagridview1.ClearSelection(); datagridview1.Rows[rowIndex - 1].Selected = true; } } 

对按钮执行相同的操作,只需在buttonDown_Click方法rowindex + 1 row indexrowIndex - 1更改为rowindex + 1

正在寻找这个向上/向下按钮的事情,很高兴我找到了这个。 最好在返回后放置bs.RaiseListChangedEvents = false语句,否则它始终不起作用。

在C#3.0中,您可以向BindingSource添加两个扩展方法,如下所示:

 public static class BindingSourceExtension { public static void MoveUp( this BindingSource aBindingSource ) { int position = aBindingSource.Position; if (position == 0) return; // already at top aBindingSource.RaiseListChangedEvents = false; object current = aBindingSource.Current; aBindingSource.Remove(current); position--; aBindingSource.Insert(position, current); aBindingSource.Position = position; aBindingSource.RaiseListChangedEvents = true; aBindingSource.ResetBindings(false); } public static void MoveDown( this BindingSource aBindingSource ) { int position = aBindingSource.Position; if (position == aBindingSource.Count - 1) return; // already at bottom aBindingSource.RaiseListChangedEvents = false; object current = aBindingSource.Current; aBindingSource.Remove(current); position++; aBindingSource.Insert(position, current); aBindingSource.Position = position; aBindingSource.RaiseListChangedEvents = true; aBindingSource.ResetBindings(false); } } 

最后很好地使用扩展方法而不是所有那些糟糕的String例子。;-)

  DataGridViewRow BeginingRow = new DataGridViewRow(); int BeginingRowIndex ; private void DataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e) { if (e.Button != MouseButtons.Left ||e.RowIndex < 0 ) return; if (BeginingRowIndex > e.RowIndex) { DataGridView1.Rows.Insert(e.RowIndex); foreach (DataGridViewCell cellules in BeginingRow.Cells) { DataGridView1.Rows[e.RowIndex].Cells[cellules.ColumnIndex].Value = cellules.Value; } DataGridView1.Rows.RemoveAt(BeginingRowIndex + 1); } else { DataGridView1.Rows.Insert(e.RowIndex +1); foreach (DataGridViewCell cellules in BeginingRow.Cells) { DataGridView1.Rows[e.RowIndex+1].Cells[cellules.ColumnIndex].Value = cellules.Value; } DataGridView1.Rows.RemoveAt(BeginingRowIndex); } DataGridView1.RowsDefaultCellStyle.ApplyStyle(BeginingRow.DefaultCellStyle); DataGridView1.Rows[e.RowIndex].Selected = true; } private void DataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) { if (e.Button != MouseButtons.Left ||e.RowIndex < 0 ) return; BeginingRowIndex = e.RowIndex; BeginingRow = DataGridView1.Rows[BeginingRowIndex]; BeginingRow.DefaultCellStyle = DataGridView1.Rows[BeginingRowIndex].DefaultCellStyle; } 
 private void butUp_Click(object sender, EventArgs e) { DataTable dtTemp = gridView.DataSource as DataTable; object[] arr = dtTemp.Rows[0].ItemArray; for (int i = 1; i < dtTemp.Rows.Count; i++) { dtTemp.Rows[i - 1].ItemArray = dtTemp.Rows[i].ItemArray; } dtTemp.Rows[dtTemp.Rows.Count - 1].ItemArray = arr; } private void butDown_Click(object sender, EventArgs e) { DataTable dtTemp = gridView.DataSource as DataTable; object[] arr = dtTemp.Rows[dtTemp.Rows.Count - 1].ItemArray; for (int i = dtTemp.Rows.Count - 2; i >= 0; i--) { dtTemp.Rows[i + 1].ItemArray = dtTemp.Rows[i].ItemArray; } dtTemp.Rows[0].ItemArray = arr; } 

这是我找到问题的最短解决方案,我只是重构了一点代码:

http://dotnetspeaks.net/post/Moving-GridView-Rows-Up-Down-in-a-GridView-Control.aspx

  

并且代码背后……

 public int SelectedRowIndex { get; set; } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { //Test Records GridView1.DataSource = Enumerable.Range(1, 5).Select(a => new { FirstName = String.Format("First Name {0}", a), LastName = String.Format("Last Name {0}", a), }); GridView1.DataBind(); } } protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer'"; e.Row.ToolTip = "Click to select row"; e.Row.Attributes["onclick"] = Page.ClientScript.GetPostBackClientHyperlink(GridView1, "Select$" + e.Row.RowIndex); } } protected void btnUp_Click(object sender, EventArgs e) { var rows = GridView1.Rows.Cast().Where(a => a != GridView1.SelectedRow).ToList(); //If First Item, insert at end (rotating positions) if (GridView1.SelectedRow.RowIndex.Equals(0)) { rows.Add(GridView1.SelectedRow); SelectedRowIndex = GridView1.Rows.Count -1; } else { SelectedRowIndex = GridView1.SelectedRow.RowIndex - 1; rows.Insert(GridView1.SelectedRow.RowIndex - 1, GridView1.SelectedRow); } RebindGrid(rows); } protected void btnDown_Click(object sender, EventArgs e) { var rows = GridView1.Rows.Cast().Where(a => a != GridView1.SelectedRow).ToList(); //If Last Item, insert at beginning (rotating positions) if (GridView1.SelectedRow.RowIndex.Equals(GridView1.Rows.Count - 1)) { rows.Insert(0, GridView1.SelectedRow); SelectedRowIndex = 0; } else { SelectedRowIndex = GridView1.SelectedRow.RowIndex + 1; rows.Insert(GridView1.SelectedRow.RowIndex + 1, GridView1.SelectedRow); } RebindGrid(rows); } private void RebindGrid(IEnumerable rows) { GridView1.DataSource = rows.Select(a => new { FirstName = ((Label)a.FindControl("txtFirstName")).Text, }).ToList(); GridView1.SelectedIndex = SelectedRowIndex; GridView1.DataBind(); } 

标题3

private void buttonX8_Click(object sender,EventArgs e)// down {DataGridViewX grid = dataGridViewX1; try {int totalRows = grid.Rows.Count; int idx = grid.SelectedCells [0] .OwningRow.Index; if(idx == totalRows – 1)返回; int col = grid.SelectedCells [0] .OwningColumn.Index; DataGridViewRowCollection rows = grid.Rows; DataGridViewRow row = rows [idx]; rows.Remove(行); rows.Insert(idx + 1,row); grid.ClearSelection(); grid.Rows [idx + 1] .Cells [col] .Selected = true;

  private void buttonX8_Click(object sender, EventArgs e)//down { DataGridViewX grid = dataGridViewX1; try { int totalRows = grid.Rows.Count; int idx = grid.SelectedCells[0].OwningRow.Index; if (idx == totalRows - 1 ) return; int col = grid.SelectedCells[0].OwningColumn.Index; DataGridViewRowCollection rows = grid.Rows; DataGridViewRow row = rows[idx]; rows.Remove(row); rows.Insert(idx + 1, row); grid.ClearSelection(); grid.Rows[idx + 1].Cells[col].Selected = true; } catch { } } 

SchlaWiener的答案运作良好,我只是想补充一点:

 private void button1_Click(object sender, EventArgs e) //The button to move up { int position = bs.Position; //.......neglected....... dataGridView1.ClearSelection(); dataGridView1.Rows[position].Selected = true; bs.MovePrevious(); } 

在底部添加这3行也可以进行选择移动(bindingSource和dataGridView),这样我们就可以连续点击底部向上移动一行。

向下移动只需调用bs.MoveNext()

(我还没有足够的声誉发表评论)

具有多选支持的数据绑定解决方案,使用SharpDevelop 4.4转换为C#。

  Sub MoveSelectionUp(dgv As DataGridView) If dgv.CurrentCell Is Nothing Then Exit Sub dgv.CurrentCell.OwningRow.Selected = True Dim items = DirectCast(dgv.DataSource, BindingSource).List Dim selectedIndices = dgv.SelectedRows.Cast(Of DataGridViewRow).Select(Function(row) row.Index).Sort Dim indexAbove = selectedIndices(0) - 1 If indexAbove = -1 Then Exit Sub Dim itemAbove = items(indexAbove) items.RemoveAt(indexAbove) Dim indexLastItem = selectedIndices(selectedIndices.Count - 1) If indexLastItem = items.Count Then items.Add(itemAbove) Else items.Insert(indexLastItem + 1, itemAbove) End If End Sub  Sub MoveSelectionDown(dgv As DataGridView) If dgv.CurrentCell Is Nothing Then Exit Sub dgv.CurrentCell.OwningRow.Selected = True Dim items = DirectCast(dgv.DataSource, BindingSource).List Dim selectedIndices = dgv.SelectedRows.Cast(Of DataGridViewRow).Select(Function(row) row.Index).Sort Dim indexBelow = selectedIndices(selectedIndices.Count - 1) + 1 If indexBelow >= items.Count Then Exit Sub Dim itemBelow = items(indexBelow) items.RemoveAt(indexBelow) Dim indexAbove = selectedIndices(0) - 1 items.Insert(indexAbove + 1, itemBelow) End Sub 

大多数post都有一种更为简单的方式(在我看来)。 执行“向上”按钮单击的操作基本上只是与上面的行交换。 如果您自己控制值(如问题所述),那么您只需要交换行的值。 快速而简单!

注意:这仅在数据网格上禁用多选时才有效! 正如您所知,我只关注SelectedRows集合中索引0处的项目。

这是我用过的:

  private void btnUp_Click(object sender, EventArgs e) { var row = dgvExportLocations.SelectedRows[0]; if (row != null && row.Index > 0) { var swapRow = dgvExportLocations.Rows[row.Index - 1]; object[] values = new object[swapRow.Cells.Count]; foreach (DataGridViewCell cell in swapRow.Cells) { values[cell.ColumnIndex] = cell.Value; cell.Value = row.Cells[cell.ColumnIndex].Value; } foreach (DataGridViewCell cell in row.Cells) cell.Value = values[cell.ColumnIndex]; dgvExportLocations.Rows[row.Index - 1].Selected = true;//have the selection follow the moving cell } } 

要执行“向下”单击,您可以执行相反的操作,相同的逻辑

试试这个:

  private void buttonX9_Click(object sender, EventArgs e)//up { DataGridViewX grid = dataGridViewX1; try { int totalRows = grid.Rows.Count; int idx = grid.SelectedCells[0].OwningRow.Index; if (idx == 0) return; int col = grid.SelectedCells[0].OwningColumn.Index; DataGridViewRowCollection rows = grid.Rows; DataGridViewRow row = rows[idx]; rows.Remove(row); rows.Insert(idx - 1, row); grid.ClearSelection(); grid.Rows[idx - 1].Cells[col].Selected = true; } catch { } }