Подтвердить что ты не робот

Выбранный ряд DataGridView Move UP и DOWN

Как разрешить перемещение выбранных строк в DataGridView (DGV) вверх или вниз. Я сделал это раньше с помощью ListView. К несчастью, для меня замена DGV не является опцией (проклятиями). Кстати, источником данных DGV является коллективная коллекция.

У DGV есть две кнопки на стороне, да, UP и Down. Может ли кто-нибудь помочь указать мне в правильном направлении. У меня есть код, который я использовал для ListView, если он поможет (мне это не помогло).

4b9b3361

Ответ 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