DataGridView选定的行向上和向下移动

Sil*_*bit 13 .net c# collections datagridview winforms

如何允许向上或向下移动DataGridView(DGV)中的选定行.我之前用ListView完成了这个.不幸的是,对我来说,更换DGV不是一种选择(诅咒).顺便说一句,DGV数据源是一个通用集合.

DGV侧面有两个按钮,是,UP和Down.任何人都可以帮我指出正确的方向.我确实有我用于ListView的代码,如果它有帮助(它没有帮助我).

Par*_*ara 30

只是为了扩展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 { }
}
Run Code Online (Sandbox Code Playgroud)

  • 也许我的DGV有一些时髦,但在向下移动时我不得不改变(idx == totalRows - 2)到(idx == totalRows - 1),否则它将允许底行被移开而倒数第二行行无法向下移动.随着变化,它对我来说完美无瑕. (3认同)
  • 这是一个比所选答案更好的答案。 (2认同)

Jür*_*ock 9

这应该工作.我使用BindingSource而不是将我的List直接绑定到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; }
    }
Run Code Online (Sandbox Code Playgroud)


Yoo*_*eek 7

如果您以编程方式更改集合中项目的顺序,则DGV应自动反映该项目.

邋,,半工作的例子:

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

其中一些逻辑可能是错误的,这可能也不是最有效的方法.此外,它没有考虑多行选择.

嗯,最后一件事,如果你使用标准的List或Collection,这将不会顺利进行.列表和集合on't发出DGV发现对数据绑定有用的事件.每次更改集合时都可以"打嗝"数据绑定,但更好的解决方案是使用System.ComponentModel.BindingList.当您更改BindingList的顺序时,DGV应自动反映更改.