【问题标题】:C# - How to pass the data from dataGridView1 to another using a button click?C# - 如何使用按钮单击将数据从 dataGridView1 传递到另一个?
【发布时间】:2017-11-23 11:18:30
【问题描述】:

我在一个表单中有一个dataGridView1dataGridView2 和一个ButtonAdd

用户将:

1- 选择任何一个“单元格”或“整行”。

2-选择多行

然后:

单击按钮时,所选数据将从 dataGridView1 移动到 dataGridView2。这就是我需要做的。

我的尝试:

经过多次搜索,我尝试了这个解决方案,几乎完成了,但有一个小问题我无法处理:

完整代码:

private const string strconneciton = @"YourConnectionString";
    SqlConnection con = new SqlConnection(strconneciton);
    SqlCommand cmd = new SqlCommand();
    DataTable dataTable;

private void loadDataIntoGridView1()
    {
        try
        {
            con.Open();
            cmd.CommandText = "SELECT id, accNum, accName FROM Employees";
            cmd.Connection = con;

            SqlDataAdapter adapter = new SqlDataAdapter();
            adapter.SelectCommand = cmd;

            dataTable = new DataTable();
            adapter.Fill(dataTable);

            BindingSource bSource = new BindingSource();
            bSource.DataSource = dataTable;
            dataGridView1.DataSource = bSource;

            //i don't know if this line is useful...
            dataGridView2.DataSource = dataTable.Clone();

            adapter.Update(dataTable);
            con.Close();

        }
        catch (Exception ed)
        {
            con.Close();
            MessageBox.Show(ed.Message);
        }
    }//end loadDataIntoGridView1


private void buttonSend_Click(object sender, EventArgs e)
{       
    if (dataGridView1.SelectedCells.Count > 0)
    {
        foreach (DataGridViewCell oneCell in dataGridView1.SelectedCells)
        {
            if (oneCell.Selected)
            {
                //this should add the rows that is selected from dataGridView1 and,
                //pass it to dataGridView2
                var currentRow = ((DataRowView)dataGridView1.CurrentRow.DataBoundItem).Row;
                 ((DataTable)dataGridView2.DataSource).ImportRow(currentRow);

                //this will remove the rows you have selected from dataGridView1
                dataGridView1.Rows.RemoveAt(oneCell.RowIndex);
            }//end if
        }//end foreach
    }//end if
}//end button click

让我们调试:

在开始之前注意一件事:

  • 删除行(多行或单行)的方法在所有情况下都可以正常工作。
  • 添加到 DGV2 的方法是个问题,我是从 here 那里得到的……它在选择单行而不是多行时工作正常。

1-如果您选择了一个单元格/行,它将成功添加和删除。

2- 如果您选择了多行,比如说第一行和第二行,它会添加第二行和第三行,然后肯定会删除它们,但只添加一个.. 为什么?!

因为这里

var currentRow = ((DataRowView)dataGridView1.CurrentRow.DataBoundItem).Row;
            ((DataTable)dataGridView2.DataSource).ImportRow(currentRow);   

获取DGV1中现有行的当前索引,并迭代选择行数并将它们添加到DGV2。

截图:

该过程如何完成的图像: .

我需要做什么:

应该怎么做才能解决这个问题?

【问题讨论】:

  • 你试过insert?
  • 不,我认为,如果您有描述“插入”的方法来解决我的问题,我将不胜感激。

标签: c# datagridview datagrid datagridviewcolumn datagridviewrow


【解决方案1】:

虽然 marco 有一点,但该行的所有权是作为异常抛出的表的。要绕过这个,你可能想这样做......

// 根据你要创建的表创建一个新行 // 插入具有相同结构的 INTO

var copyRow = table.NewRow(); 
copyRow.ItemArray = currentRow.ItemArray;
table.Rows.Add( copyRow );

ItemArray 是按顺序排列的表的所有列属性的列表,无需显式引用 Row["someColumn"]。因此,将数组复制到新行可以获得所有列。这是 - 假设两个表结构相同 - 并且似乎来自您提供的场景。

澄清

上面的代码只做一行,并且会根据你的循环应用

if (oneCell.Selected)

您在每行中选择了多个列,从而对循环造成了一些混乱。您实际上多次击中同一行。无论如何,我发现您实际上是在 Windows 应用程序中执行此操作,而不是 WPF。我创建了一个表单并在下面发布了代码。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        loadDataIntoGridView1();
    }

    public DataTable tblFrom { get; set; }
    public DataTable tblTo { get; set; }
    private void loadDataIntoGridView1()
    {
        tblFrom = new DataTable();
        tblFrom.Columns.Add("Col1", typeof(string));
        tblFrom.Columns.Add("Col2", typeof(string));

        tblTo = tblFrom.Clone();

        DataRow tmp;
        while (tblFrom.Rows.Count < 20)
        {
            tmp = tblFrom.NewRow();
            tmp["Col1"] = "my row " + tblFrom.Rows.Count;
            tmp["Col2"] = "testing";
            tblFrom.Rows.Add(tmp);
        } 

        dataGridView1.AutoGenerateColumns = true;
        dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
        dataGridView2.AutoGenerateColumns = true;
        dataGridView2.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
        dataGridView1.DataSource = tblFrom;
        dataGridView2.DataSource = tblTo;
    }

    private void button1_Click(object sender, System.EventArgs e)
    {
        // if no ROWS selected, get out.
        if (dataGridView1.SelectedRows.Count == 0)
            return;

        foreach( DataGridViewRow vr in dataGridView1.SelectedRows)
        {
            var currentRow = ((DataRowView)vr.DataBoundItem).Row;
            ((DataTable)dataGridView2.DataSource).ImportRow(currentRow);

            //this will remove the rows you have selected from dataGridView1
            dataGridView1.Rows.RemoveAt(vr.Index);
        }
    }
}

在这里,我有一个表格,其中有两个网格,类似于您的表格,还有一个“移动”记录的按钮(但只有一个方向),您必须针对一个/全部/从/到方向进行调整。

一些变化。我更改了网格以强制选择模式为整个 ROW。这将防止单行出现多个条目,因为您有多个可用列。通过在单元格之间拖动或 Ctrl+单击单个行仍然可以进行多选。这允许选择不在同一可视屏幕区域内的行。

我还刚刚做了一个创建表来强制模拟 20 行数据以强制并非所有行同时可见。

接下来是点击事件...如果没有选择 ROWS,请退出...如果有,请循环执行,但如果多列,这将执行 ONE PER ROW 而不是多次。获取绑定数据行,导入删除...

否则你非常接近并且不需要复制数组。我认为总体问题是您的列模式选择多次达到相同的记录。在第一个单元格的第 0 行删除后,第 1 行变为第 0 行,因此将其复制,删除,您现在不在列表中,因为只剩下一条记录要处理。在这里,我们得到了整行 ONCE,而不管它选择了哪一列。

【讨论】:

  • 此代码复制所有数据并将其放入另一个 DataGridView...实际上它并不能完成我的工作。我只想复制选定的行,即使我选择一行,它也会获取所有行
  • @MahmoudAyman,不,这仅根据选择的任何行执行单行...如果您有一个包含 20 列的表,而不是复制每一列,ItemArray 包含所有 20 个元素,甚至如果表中有 5 行实际数据。
  • ,是的,我明白......但我需要做的是选择特定的多行并将它们复制到另一个 DGV..“不是所有行”但是只有选定的,...您的代码复制所有行,但这不是我需要的。我添加了我需要做的截图。如果您已经测试过代码,请将其粘贴到此处以正确方式进行。
  • 感谢@DRapp,现在它对我有用,非常感谢您的回答
【解决方案2】:

代替

ImportRow(currentRow)

使用这样的东西:

table.Rows.Add(currentRow);

让我知道这是否有效!

【讨论】:

  • 它抛出一个异常:“System.ArgumentException:该行已经属于另一个表。”
【解决方案3】:

这是一个完整的 sn-p。 在此示例中,我使用 2 BindingList 来满足您的要求。用户单击按钮后,示例会将所选项目从dgv1data 复制到dgv2data。然后它将从dgv1data 中删除项目。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace MoveDataBetweenDataGridView_47454256
{
    public partial class Form1 : Form
    {
        static BindingList<dgventry> dgv1data = new BindingList<dgventry>();
        static BindingList<dgventry> dgv2data = new BindingList<dgventry>();
        DataGridView dgv1 = new DataGridView();
        DataGridView dgv2 = new DataGridView();
        Button btn = new Button();

        public Form1()
        {
            InitializeComponent();

            InitOurStuff();
            for (int i = 0; i < 10; i++)
            {
                dgv1data.Add(new MoveDataBetweenDataGridView_47454256.dgventry
                {
                    col1 = $"col1_{i}", col2 = $"col2_{i}", col3 = $"col3_{i}"});
                }

        }

        private void InitOurStuff()
        {
            this.Controls.Add(dgv1);//add the DGV to the form
            dgv1.DataSource = dgv1data;//bind our data to it
            dgv1.Dock = DockStyle.Left;//place the DGV somewhere on the form

            this.Controls.Add(dgv2);//add the DGV to the form
            dgv2.DataSource = dgv2data;//bind out data to it
            dgv2.Dock = DockStyle.Right;//place the DGV somewhere on the form

            this.Controls.Add(btn);//add the Button to the form
            btn.Dock = DockStyle.Bottom;//place the Button somewhere on the form
            btn.Click += Btn_Click;//give the Button a event handler
        }




        private void Btn_Click(object sender, EventArgs e)
        {
            List<int> doneIndices = new List<int>();//this will keep track of the row indices we have dealt with

            if (dgv1.SelectedCells.Count > 0)//if something is selected
            {
                foreach (DataGridViewCell item in dgv1.SelectedCells)//loop through the selected cells
                {
                    if (!doneIndices.Contains(item.OwningRow.Index))//if this cell does not belong to a row index we already processed
                    {
                        //we haven't done this row yet
                        dgv2data.Add((dgventry)item.OwningRow.DataBoundItem);//add the DataBoundItem to the other DGV data
                        doneIndices.Add(item.OwningRow.Index);//put the current row index in our tracking list
                    }
                    else
                    {
                        //we have done this row already, move on to the next one
                        continue;
                    }
                }
            }

            //remove all the duplicate entries
            foreach (dgventry item in dgv2data)
            {
                dgv1data.Remove(item);
            }
        }
    }



    public class dgventry
    {
        public string col1 { get; set; }
        public string col2 { get; set; }
        public string col3 { get; set; }

    }
}

【讨论】:

    猜你喜欢
    • 2014-01-01
    • 1970-01-01
    • 2016-12-25
    • 2013-01-24
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    相关资源
    最近更新 更多