wake-up-neo.com

DataGridView Ausgewählte Zeile Nach oben und unten bewegen

Wie kann ich zulassen, dass ausgewählte Zeilen in einem DataGridView (DGV) nach oben oder unten verschoben werden. Ich habe das vorher mit einer ListView gemacht. Leider ist der Ersatz des DGV für mich keine Option ( curses ). Bei der DGV-Datenquelle handelt es sich übrigens um eine Generic Collection.

Der DGV hat zwei Knöpfe an der Seite, ja, UP und Down. Kann mir jemand helfen, in die richtige Richtung zu weisen. Ich habe den Code, den ich für ListView verwendet habe, wenn es helfen würde (es hat mir nicht geholfen).

11
Silly Rabbit

Wenn Sie die Reihenfolge der Artikel in Ihrer Sammlung programmgesteuert ändern, sollte die DGV dies automatisch widerspiegeln. 

Sloppy, halb arbeitendes Beispiel:

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

Einige dieser Logik sind möglicherweise falsch, und dies ist möglicherweise auch nicht der effizienteste Ansatz. Es berücksichtigt auch nicht die Auswahl mehrerer Zeilen.

Hmm, eine letzte Sache, wenn Sie eine Standardliste oder Collection verwenden, wird dies nicht so reibungslos verlaufen. List and Collection emittiert keine Ereignisse, die nach Ansicht der DGV für das Datenbinden nützlich sind. Sie könnten die Datenbindung jedes Mal "rülpsen", wenn Sie die Sammlung ändern. Eine bessere Lösung wäre die Verwendung einer System.ComponentModel.BindingList. Wenn Sie die Reihenfolge der BindingList ändern, sollte die DGV die Änderung automatisch widerspiegeln.

6
Yoopergeek

Um nur die Antwort von Yoopergeek zu erweitern, habe ich Folgendes: Ich habe keine DataSource verwendet (die Daten werden beim Schließen des Formulars in die Registrierung gelöscht und beim Laden des Formulars neu geladen).

Dieses Beispiel verhindert, dass Zeilen aus dem Raster verschoben werden und verloren gehen. Außerdem wird die Zelle, in der sich die Person befand, erneut ausgewählt.

Um das Kopieren und Einfügen zu vereinfachen, habe ich die Änderungen so vorgenommen, dass Sie nur "gridTasks" in den Namen Ihrer DataGridView ändern müssen, anstatt ihn im gesamten Code umzubenennen.

Diese Lösung funktioniert nur für eine ausgewählte Zelle/Zeile.

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 { }
}
27
Para

Das sollte funktionieren. Ich verwende eine BindingSource, anstatt meine Liste direkt an DataGridView zu binden:

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

Füllen Sie zuerst Ihren Datagridview, zum Beispiel haben Sie eine Tabelle mit 3 Spalten

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;

Klicken Sie dann auf die Schaltfläche und klicken Sie auf

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

Machen Sie dasselbe für die Schaltfläche, ändern Sie einfach row index von rowIndex - 1 in rowindex + 1 in Ihrer buttonDown_Click-Methode

1
Nikola Glisic
   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;
    }
0
user411188

Es gibt einen viel einfacheren Weg, den die meisten Beiträge hier (meiner Meinung nach) veröffentlichen. Das Durchführen der Aktion für einen Klick auf die Schaltfläche "Auf" ist im Wesentlichen nur ein Austausch von Zeilen mit den obigen. Wenn Sie die Werte selbst kontrollieren (wie die Frage angegeben wurde), müssen Sie nur die Werte der Zeilen vertauschen. Schnell und einfach! 

HINWEIS: Dies funktioniert nur, wenn Multiselect auf dem Datagrid deaktiviert ist! Wie Sie sehen, schaue ich nur auf item bei Index 0 in der SelectedRows-Sammlung.

Folgendes habe ich verwendet: 

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

Um einen "Down" -Klick auszuführen, können Sie auch das Gegenteil machen, dieselbe Logik

0
Matt0

dies ist die kürzeste Lösung, die ich für das Problem gefunden habe, und ich habe den Code ein wenig überarbeitet: 

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>

und mit Code hinter ...

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

Kopfzeile 3

private void buttonX8_Click (Objektsender, EventArgs e) // down { DataGridViewX-Raster = dataGridViewX1; try { int totalRows = Gitter .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 = Zeilen [idx]; row.Remove (row) ; Zeilen.Einfügen (idx + 1, Zeile); 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

datengebundene Lösung mit Multi-Selection-Unterstützung: Verwenden Sie SharpDevelop 4.4, um in C # zu konvertieren.

<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
stax76
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;
}
0
namco

SchlaWieners Antwort hat gut funktioniert, und ich möchte einfach etwas dazu hinzufügen:

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

}

Fügen Sie diese drei Zeilen unten hinzu, um auch die Auswahl zu verschieben (sowohl bindingSource als auch dataGridView), sodass wir fortlaufend auf den unteren Bereich klicken können, um eine Zeile nach oben zu verschieben.

Zum Abwärtsfahren rufen Sie einfach bs.MoveNext () auf.

(Ich habe noch nicht genug Ruf, um als Kommentar zu posten)

0
Yang Chi-En

War auf der Suche nach dieser UP/DOWN-Taste und bin froh, dass ich das hier gefunden habe. Besser die bs.RaiseListChangedEvents = false -Anweisung nach der Rückkehr, oder sie funktioniert nicht immer.

In C # 3.0 können Sie der BindingSource zwei Erweiterungsmethoden wie folgt hinzufügen:

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

Endlich eine gute Verwendung für Erweiterungsmethoden anstelle all der schlechten String-Beispiele .. ;-)

0
user220630