Выбранный ряд DataGridView Move UP и DOWN
Как разрешить перемещение выбранных строк в DataGridView (DGV) вверх или вниз. Я сделал это раньше с помощью ListView. К несчастью, для меня замена DGV не является опцией (проклятиями). Кстати, источником данных DGV является коллективная коллекция.
У DGV есть две кнопки на стороне, да, UP и Down. Может ли кто-нибудь помочь указать мне в правильном направлении. У меня есть код, который я использовал для ListView, если он поможет (мне это не помогло).
Ответы
Ответ 1
Если вы программно изменяете порядок элементов в своей коллекции, DGV должен отражать это автоматически.
Неактивный, полуобработанный пример:
List<MyObj> foo = DGV.DataSource;
int idx = DGV.SelectedRows[0].Index;
int value = foo[idx];
foo.Remove(value);
foo.InsertAt(idx+1, value)
Некоторые из этой логики могут быть ошибочными, и это может быть и не самый эффективный подход. Кроме того, он не учитывает выбор нескольких строк.
Хм, последнее, если вы используете стандартный список или коллекцию, это не будет идти гладко. List и Collection не генерируют события, которые DGV находит полезными для привязки данных. Вы можете "отрыгать" привязку данных каждый раз, когда вы меняете коллекцию, но лучшим решением будет использование System.ComponentModel.BindingList. Когда вы изменяете порядок BindingList, DGV должен автоматически отражать изменение.
Ответ 2
Просто, чтобы расширить ответ 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 { }
}
Ответ 3
Это должно сработать. Я использую BindingSource вместо привязки своего списка непосредственно к DataGridView:
private List<MyItem> items = new List<MyItem> {
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; }
}
Ответ 4
Сначала заполните ваше 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;
}
}
Сделайте то же самое для кнопки вниз, просто измените row index
от rowIndex - 1
до rowindex + 1
в методе buttonDown_Click
Ответ 5
Ищет эту кнопку UP/DOWN и рад, что нашел это.
Лучше поместить инструкцию bs.RaiseListChangedEvents = false после возвращения или она не работает все время.
И в С# 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..; -)
Ответ 6
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;
}
Ответ 7
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;
}
Ответ 8
это кратчайшее решение, которое я нашел для проблемы, и я просто немного переработал код, найденный в:
http://dotnetspeaks.net/post/Moving-GridView-Rows-Up-Down-in-a-GridView-Control.aspx
<body>
<form id="form1" runat="server">
<asp:GridView ID="GridView1" Font-Names="Verdana" Font-Size="9pt" runat="server" OnRowCreated="GridView1_RowCreated"
AutoGenerateColumns="False" CellPadding="4" BorderColor="#507CD1" BorderStyle="Solid">
<Columns>
<asp:TemplateField HeaderText="First Name">
<ItemTemplate>
<asp:Label ID="txtFirstName" runat="server" Text='<%# Eval("FirstName") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:Button ID="btnUp" runat="server" Text="Up" OnClick="btnUp_Click"/>
<asp:Button ID="btnDown" runat="server" Text="Down" OnClick="btnDown_Click" />
</form>
и с кодом позади...
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<GridViewRow>().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<GridViewRow>().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<GridViewRow> rows)
{
GridView1.DataSource = rows.Select(a => new
{
FirstName = ((Label)a.FindControl("txtFirstName")).Text,
}).ToList();
GridView1.SelectedIndex = SelectedRowIndex;
GridView1.DataBind();
}
Ответ 9
Заголовок 3
private void buttonX8_Click (отправитель объекта, EventArgs e)//вниз { DataGridViewX grid = dataGridViewX1; пытаться { 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 { }
}
Ответ 10
Ответ 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()
(У меня недостаточно репутации, чтобы опубликовать комментарий)
Ответ 11
с поддержкой множественного выбора, используйте SharpDevelop 4.4 для преобразования в С#.
<Extension()>
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
<Extension()>
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
Ответ 12
Попробуйте следующее:
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 { }
}
Ответ 13
Уверен, что вы решили эту проблему, но это простой ответ, который я хотел бы поделиться.
Private Sub btnSUp_Click(sender As Object, e As EventArgs) Handles btnSUp.Click
MoveDgvItem(-1, dgvSort)
End Sub
Private Sub btnSDown_Click(sender As Object, e As EventArgs) Handles btnSDown.Click
MoveDgvItem(1, dgvSort)
End Try
Public Sub MoveDgvItem(direction As Int16, dgv As DataGridView)
' Checking selected item
If dgv.CurrentRow Is Nothing Or dgv.SelectedRows.Count < 0 Then Exit Sub
' Calculate New index using move direction
Dim newIndex As Int16 = dgv.Rows.IndexOf(dgv.SelectedRows(0)) + direction
' Checking bounds of the range
If newIndex < 0 Or newIndex >= dgv.Rows.Count Then Exit Sub
Dim row = New String() {dgv.SelectedRows(0).Cells(0).Value.ToString, dgv.SelectedRows(0).Cells(1).Value.ToString}
Dim selected As Object = dgv.SelectedRows(0)
' Removing removable element
dgv.Rows.Remove(selected)
' Insert it in New position
dgv.Rows.Insert(newIndex, row)
' Restore selection
dgv.Rows(newIndex).Selected = True
End Sub