2

I have DataGridView which is bounded with a datatable. I fill this datatable from database. I have 2 buttons right next to the datagridview, Up and Down. the rows should move up and down based on whichever button i click. I understand there are many answers for the similar issues but they work if your gridview isnt bounded. I also have a sequence column which has numbers from 0 onwards. When the rows move up or down, the sequence should be fixed as well. For example, if i move row[12] up, the sequence of row[12] should update to row[11] and row[11] should move down and row[11] sequence becomes row[12]. (I'm sorry if this is confusing). I also have 2 event functions attached to up and down buttons as well.

Edit: The main goal of this gridview is that user can add new rows as well. So, along with the above information, if there are 5 rows with sequence 1 to 5, and the user adds another row with sequence 2. I can sort the rows but how do I make the origninal rows with sequence 2,3,4,5 shift down and change their sequence to 3,4,5,6?

private void moveRow(int position)
    {
        DataRow selectedDataRow = null;
        DataRow newDataRow = null;
        int sequence = -1;
        int newSequence = -1;
        DataGridViewRow selectedRow = dataGridView.SelectedRows[0];
        sequence = (int)selectedRow.Cells[sequenceDataGridViewTextBoxColumn.Index].Value;
        newSequence = sequence + position;
        if (newSequence <= 0 || newSequence > dataGridView.Rows.Count)
        {
            return;
        }



        //below code doesnt work at all maybe cuz it isnt right
        //How do i select the current row and the row at the new sequence?????



            if (selectedDataRow != null && newDataRow != null)
            {//below i try to assign sequences to the rows
                selectedDataRow["Sequence"] = newSequence;
                newDataRow["Sequence"] = sequence;
            }
            dataGridViewRed.Sort(dataGridViewRed.Columns[buildSequenceDataGridViewTextBoxColumn.Index], ListSortDirection.Ascending);// i sort it again based on sequence
            dataGridViewRed.CurrentCell = dataGridViewRed.Rows[selectedRow.Index + position].Cells[buildSequenceDataGridViewTextBoxColumn.Index];//highlight the current selected cell
//below functions are the events attached to the buttons for up and down
private void UpBtn_Click(object sender, EventArgs e)
    {
        moveRow(-1);
    }

    private void DownBtn_Click(object sender, EventArgs e)
    {
        moveRow(+1);
    }

There are definitely some loopholes in my explanation so please be kind. I will do my best to explain any confusions, if need be.

1 Answers1

3

If your rows are bound, then following example is applicable for moving row up. Prober Bounding should take care about sorting the DataGridView on the screen. If you sorted it in the data bound source, then it should work without .Sort, I think (I didn't test that).

If the row numbering could be inconsistent (c#):

DataGridViewRow SelectedDataRow = ...;
if (SelectedDataRow.Index > 0)
{
    DataGridViewRow PrevDataRow = DataGridView1.Rows(SelectedDataRow.Index - 1);
    Int16 PrevSequence = PrevDataRow.Cells("Sequence").Value;  // buffer the previous sequence
    PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Cells("Sequence").Value;    // set previous sequence to selected
    SelectedDataRow.Cells("Sequence").Value = PrevSequence;                           // set selected to previous
} 

VB.NET:

        Dim SelectedDataRow As DataGridViewRow = ...
        If SelectedDataRow.Index > 0 Then
            Dim PrevDataRow As DataGridViewRow = DataGridView1.Rows(SelectedDataRow.Index - 1)
            Dim PrevSequence As Int16 = PrevDataRow.Cells("Sequence").Value  ' buffer the previous sequence
            PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Cells("Sequence").Value    ' set previous sequence to selected
            SelectedDataRow.Cells("Sequence").Value = PrevSequence                           ' set selected to previous
        End If

If the rownumbering is consistent (continuous 1 to N), then it can be simplified:

DataGridViewRow SelectedDataRow = ...;
if (SelectedDataRow.Index > 0)
{
    DataGridViewRow PrevDataRow = DataGridView1.Rows(SelectedDataRow.Index - 1);
    PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Index + 1;
    SelectedDataRow.Cells("Sequence").Value = SelectedDataRow.Index;                            // set selected to previous
}

VB.NET:

        Dim SelectedDataRow As DataGridViewRow = ...
        If SelectedDataRow.Index > 0 Then
            Dim PrevDataRow As DataGridViewRow = DataGridView1.Rows(SelectedDataRow.Index - 1)
            PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Index + 1
            SelectedDataRow.Cells("Sequence").Value = SelectedDataRow.Index                            ' set selected to previous
        End If

The moving down is similar, just the condition takes into account a limit of number of rows.

While this worked for me in similar scenario, I usually don't use binding in such scenarios, I use a DataTable as a data mediator.

Oak_3260548
  • 1,882
  • 3
  • 23
  • 41
  • Your answer works. but i had to change `PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Index + 1; SelectedDataRow.Cells("Sequence").Value = SelectedDataRow.Index; ` to the following: `PrevDataRow.Cells("Sequence").Value = SelectedDataRow.Index; SelectedDataRow.Cells("Sequence").Value = SelectedDataRow.Index+1;` – Waleed Mahmood Jul 24 '19 at 15:50
  • Sorry for that, the former is for row numbering starting with 0. Glad it helped a bit. – Oak_3260548 Jul 25 '19 at 07:39