DataGridView Selected Row Move UP and DOWN

后端 未结 13 1459
盖世英雄少女心
盖世英雄少女心 2020-12-06 01:31

How can I allow selected rows in a DataGridView (DGV) to be moved up or down. I have done this before with a ListView. Unfortunetly, for me, replacing the DGV is not an opt

相关标签:
13条回答
  • 2020-12-06 02:08

    SchlaWiener's answer worked well, and I just wanna add something to it:

    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();
    
    }
    

    Adding those 3 lines at the bottom to also make the selection move (both bindingSource and dataGridView), so that we can continuously click the bottom to move a row up.

    For moving down just call bs.MoveNext()

    (I have not enough reputation to post as comment yet)

    0 讨论(0)
  • 2020-12-06 02:09

    data bound solution with multi-selection support, use SharpDevelop 4.4 to convert to C#.

    <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
    
    0 讨论(0)
  • 2020-12-06 02:12

    Header 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 ) 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;

          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 { }
        }
    
    0 讨论(0)
  • 2020-12-06 02:17

    Was looking for this UP/DOWN button thing and glad that I found this. Better to put the bs.RaiseListChangedEvents = false statement after the return or it doesn't work all the time.

    And in C#3.0 you can add two extension methods to the BindingSource like this:

    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);
        }
    }
    

    Finally a good use for extension methods instead of all those bad String examples.. ;-)

    0 讨论(0)
  • 2020-12-06 02:18

    First fill your datagridview,for example you got table with 3 colums

    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;
    

    Then, on button up click

    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;
        }
    }
    

    Do the same thing for button down, just change row index from rowIndex - 1 to rowindex + 1 in your buttonDown_Click method

    0 讨论(0)
  • 2020-12-06 02:19

    If you programatically change the ordering of the items in your collection, the DGV should reflect that automatically.

    Sloppy, half-working example:

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

    Some of that logic may be wrong, and this may not be the most efficient approach either. Also, it doesn't take into account multiple row selections.

    Hmm, one last thing, if you're using a standard List or Collection this isn't going to go as smoothly. List and Collection on't emit events that the DGV finds useful for databinding. You could 'burp' the databinding every time you change the collection, but a better solution would be for you to use a System.ComponentModel.BindingList. When you change the ordering of the BindingList the DGV should reflect the change automatically.

    0 讨论(0)
提交回复
热议问题