【问题标题】:how to compare two dgv and pass datagridview to another Form c#如何比较两个 dgv 并将 datagridview 传递给另一个 Form c#
【发布时间】:2018-08-27 12:19:36
【问题描述】:

我有两个datagridview,每个都包含两列和相同的行数。我使用这个循环比较了这两个datagridview:

 int result = 0;
 for (int i=0;i< dgvInvent1.RowCount;i++)
 {
   var src1 = dgvInvent1.Rows[i].Cells[1].Value.ToString();
   var src2 = dgvInvent2.Rows[i].Cells[1].Value.ToString();
   result = Int32.Parse(src1) - Int32.Parse(src2);
 }

我也想将结果转移到另一个datagridview,我将它命名为“dgvFinal”,除了dvgFinal是我刚刚创建的另一个名为“Form2”的表单,所以我将此行添加到form2

public DataGridView dvgFinal { get; set; }

并在我的主表单中添加到我的循环中

Form2 re = new Form2();
            int result = 0;
            for (int i=0;i< dgvInvent1.RowCount;i++)
            {
                var src1 = dgvInvent1.Rows[i].Cells[1].Value.ToString();
                var src2 = dgvInvent2.Rows[i].Cells[1].Value.ToString();
                 result = Int32.Parse(src1) - Int32.Parse(src2);
                re.dvgFinal.Rows[i].Cells[2].Value = result;
            }

但它不起作用,我明白了

System.NullReferenceException was unhandled
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.

有人可以帮助我吗? 提前谢谢你

【问题讨论】:

  • 您有 2 个具有相同列和行的 dgv,您必须从 dgvInvent1 减去第 1 列到 dgvInvent2 并在另一个来自的第三个 dgv 中显示结果,对吧?
  • 对对对
  • 在您执行此循环时,“dvgFinal”的行数(至少三列)是否与“dgvInvent1”一样多?
  • 不,'dvgFinal' 不包含任何数据,只是我预定义的列

标签: c# .net winforms datagridview


【解决方案1】:
Form2 re = new Form2();
int result = 0;
for (int i=0 ;i< dgvInvent1.RowCount; i++)
{
    var src1 = (int)dgvInvent1.Rows[i].Cells[1].Value;
    var src2 = (int)dgvInvent2.Rows[i].Cells[1].Value;
    result = src1 - src2;
    re.dvgFinal.Rows.Add(result.ToString());
}

这应该适合你。原因是您尝试访问尚不存在的行。

但是,请考虑改用数据源。

【讨论】:

  • 运算符“-”不能应用于“对象”类型的操作数
  • @kevin73 查看我编辑的答案。在对它们执行操作之前,您需要将单元格的值转换为 int
  • 在 WindowsFormsApplication1.exe code 中发生了“System.NullReferenceException”类型的未处理异常
  • re.dvgFinal.Rows.Add(result.ToString());最后一行
  • 这意味着表单还没有初始化。 dvgFinal 仍然是null。您需要在表单初始化后运行此代码。
【解决方案2】:

1) 使用DataTable 加载所有结果,例如。

Form5 re = new Form5();
int result = 0;
DataTable dt = new DataTable();
dt.Columns.Add("Result");

for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
    DataRow row = dt.NewRow();
    var src1 = dataGridView1.Rows[i].Cells[0].Value;
    var src2 = dataGridView2.Rows[i].Cells[0].Value;
    result = Convert.ToInt32(src1) - Convert.ToInt32(src2);

    row["Result"] = result;
    dt.Rows.Add(row);

}

re.DataTable = dt;
re.Show();

2) 在目标表单上创建DataTable 的新公共属性,以便我们可以从源表单访问它,例如

public DataTable DataTable { get; set; }

3) 从工具箱或代码中添加一个DataGridView 到目标表单,例如dgvFinal

如果您想手动将列添加到您的 dgvFinal,则从属性窗口将其 ColumnType 设置为 DataGridViewTextBoxColumn 并将 DataPropertyName 设置为 Result

4) 将Form_Load 方法添加到您的目标表单并分配DataSource

private void Form5_Load(object sender, EventArgs e)
{
    this.dgvFinal.DataSource = DataTable;
}

输出:

源表单

目标形式

编辑:

如果您想为 datagridview 中的每一列设置自定义标题名称,请设置 HeaderText 值。

在这种情况下,datagridview 是您的dgvFinal

选择 datagridview => 打开属性窗口 => 选择列属性 => 选择所需的列 => 选择并设置 HeaderText 值。

如果你想在你的 dgvFinal 中添加更多的列,那么你可以在上面列出的第 1 点中的数据表中添加相应的列,例如

dt.Columns.Add("Result1");
dt.Columns.Add("Result2");
dt.Columns.Add("Result3");

在 for 循环中,您可以为每个列分配行值,例如

result1 = Convert.ToInt32(src1) - Convert.ToInt32(src2);
result2 = Convert.ToInt32(src1) + Convert.ToInt32(src2);
result3 = Convert.ToInt32(src1) * Convert.ToInt32(src2);

row["Result1"] = result1;
row["Result2"] = result2;
row["Result3"] = result3;  

您可以为每一行分配任何值,它可能来自您的dgvInvent1 或来自dgvInvent2 或您的任何计算值。

最后为上面的每一列设置HeaderText 值 在dgvFinal

【讨论】:

  • 您能给我们一个支持“DataTable 始终最好用作 DataGridView 的 DataSource”语句的参考吗?谁说的?
  • 这是我的个人经验,我几乎使用DataTableDataGridView 绑定,因为我的大多数项目都适合,如果你不想要这条线,我会删除它跨度>
  • @ershoaib “结果”列不属于该表。但我只是在我的表格中改变了它,或者它可能是另一个?
  • @kevin73,你从哪里得到这个错误?如果您在目标表单的 datagridview 上遇到此错误,如果您在此 datagridview 中只有一列,则从中删除列
  • @kevin73,我做了一些更新来回答,请仔细查看这些更改:)
【解决方案3】:

这是一个完整的工作示例:

void Main()
{
    DataTable tbl1 = new DataTable();
    DataTable tbl2 = new DataTable();

    using (SqlConnection con = new SqlConnection(@"server=.\SQLExpress;Database=Test;Trusted_Connection=yes"))
    {
        string query = @"with myTally (N) as (
             select top(10) row_number() over (order by t1.object_id)
             from sys.all_columns t1 
             cross join sys.all_columns t2)
             select cast(N * 1000 * rand() as int) as col1, cast(N * 100 * rand() as int) as col2
             from myTally";
             con.Open();
        tbl1.Load(new SqlCommand(query, con).ExecuteReader());
        tbl2.Load(new SqlCommand(query, con).ExecuteReader());
    }

    Form f1 = new Form();
    var dgv1 = new DataGridView { Top = 10, Left = 10, Height = 100, DataSource = tbl1 };
    var dgv2 = new DataGridView { Top = 130, Left = 10, Height = 100, DataSource = tbl2 };
    var btn = new Button {Top=250, Left=10, Text="Show 3rd Grid"};

    f1.Controls.AddRange(new Control[] {dgv1, dgv2, btn});

    btn.Click += (sender, args) =>
    {
        DataTable tbl3 = new DataTable();
        tbl3.Columns.Add("Result", typeof(int));
        for (int i = 0; i < tbl1.Rows.Count; i++)
        {
            tbl3.Rows.Add((int)tbl1.Rows[i]["col1"] - (int)tbl2.Rows[i]["col1"]);
        }

        Form f2 = new Form();
        var dgv3 = new DataGridView {Dock=DockStyle.Fill, DataSource=tbl3};
        f2.Controls.Add(dgv3);
        f2.ShowDialog();
    };

    f1.Show();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    相关资源
    最近更新 更多