1

I have two datagridview that each contain two columns and the same numbers of rows.I compared these two datagridview using this loop :

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

I want to transfer the result to another datagridview too, I named it "dgvFinal" , except that dvgFinal is in another form called "Form2" that I just created , so i added this line to form2

public DataGridView dvgFinal { get; set; }

and in my main Form i added to my loop

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

but it doesn't work , i get

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

someone could help me ? Thank you in advance

  • 1
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Henrik Wilshusen Aug 27 '18 at 12:23
  • you have 2 dgv with same columns and rows and you have to subtract column 1 from `dgvInvent1` to `dgvInvent2` and display result in third dgv that is on another from, right? – er-sho Aug 27 '18 at 12:23
  • yes yes exactly –  Aug 27 '18 at 12:24
  • Does 'dvgFinal' have as many rows (and at least three columns) as 'dgvInvent1' at the time you execute this loop? – oerkelens Aug 27 '18 at 12:24
  • No , 'dvgFinal' does not contain any data just columns that I have predefined –  Aug 27 '18 at 12:26
  • Why wouldn't you work with the Datasource instead? – Cetin Basoz Aug 27 '18 at 12:30
  • Why in the world you convert the values ToString() and do an Int32.Parse!!! Why not directly use the Value??? – Cetin Basoz Aug 27 '18 at 12:32
  • how to transfer then the result with datasource? –  Aug 27 '18 at 12:33
  • if dgvFinal has know rows, then why you are accessing its rows? AAlso make sure the dgvFinal is not null – Plexis Plexis Aug 27 '18 at 12:33
  • @CetinBasoz sorry i am beginner in C# :D –  Aug 27 '18 at 12:34
  • You didn't even tell us what your datasource is. How do you get the data into Datagrid1 and 2 in the first place? – Cetin Basoz Aug 27 '18 at 12:51
  • i get the data from mysql database –  Aug 27 '18 at 12:53
  • Oh Kevin, getting information from you is very hard. How do you do that? There are N ways you know, don't you? If you are getting it from the database, why wouldn't you simply get the 3rd from database is very questionable. – Cetin Basoz Aug 27 '18 at 12:55
  • i use Datasource to load the data , dgvInvent1.DataSource = db.query("SELECT idMarq , nomMarq FROM marques"); –  Aug 27 '18 at 12:56
  • What is db.query? At least tell us what it returns? – Cetin Basoz Aug 27 '18 at 13:01
  • @CetinBasoz its returns Datatable –  Aug 27 '18 at 13:07
  • OK then it has a DataRow collection that you can query with Linq. Simply query and select into a datatable for 3rd grid. I will soon post a sample (mine would be from SQL server as a sample, but doesn't matter). – Cetin Basoz Aug 27 '18 at 13:10

3 Answers3

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

This should work for you. The reason is that you try to access rows that aren't there yet.

However, consider using Datasource instead.

Viggo Lundén
  • 696
  • 1
  • 6
  • 30
1

1) Use DataTable to load all your results like.

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) Create a new public property of DataTable on target form so we can access it from our source form like

public DataTable DataTable { get; set; }

3) Add one DataGridView from toolbox or from code to target form like dgvFinal.

If you want to manually add column to your dgvFinal then set it ColumnType to DataGridViewTextBoxColumn and DataPropertyName to Result from property window.

4) Add Form_Load method to your target form and assign DataSource

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

Output:

Source Form

enter image description here

Target Form

enter image description here

Edit:

If you want to set custome header name for each of your column in datagridview then set HeaderText value.

In this case the datagridview is your dgvFinal

Select datagridview => open property window => choose columns property => choose your desired column => choose and set HeaderText value.

If you want to add more columns in your dgvFinal then you can add repective columns in your datatable in point no 1 listed above like

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

And in for loop you can assign rows value to each of your column like

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;  

You may assign any values to each of your row, it may be from your dgvInvent1 or from dgvInvent2 or any of your calculated values.

And finally set HeaderText values for each of your above column in dgvFinal

er-sho
  • 8,871
  • 2
  • 10
  • 23
  • Can you give us a reference that backs up the statement "DataTable is always best to use as DataSource to DataGridView"? Who said that? – Cetin Basoz Aug 27 '18 at 13:08
  • this is my personal experience that I almost use `DataTable` as binding with `DataGridView` bcoz most of my projects its suitable, If you don't want this line then I'll remove it – er-sho Aug 27 '18 at 13:12
  • @ershoaib The 'result' column does not belong to the table. But i just changed it in my form , or maybe it's another ? –  Aug 27 '18 at 13:27
  • @kevin73, where did u got this error? If you got this error on target form's `datagridview` then remove columns from it if you have only one column in this `datagridview` – er-sho Aug 27 '18 at 13:33
  • @kevin73, I made some updates to answer please view those changes carefully :) – er-sho Aug 27 '18 at 15:07
  • @ershoaib it works now , thank you. I just tried it. But i'd like too copy all column first to display names with result now –  Aug 27 '18 at 15:37
  • @kevin73, could you pease elaborate this => But i'd like too copy all column first to display names with result now , so I'll can update answer :) – er-sho Aug 27 '18 at 15:49
  • @kevin73, view the edit section in answer might be it help you for your last comment, if it help then accept answer or let me know . – er-sho Aug 28 '18 at 01:50
  • @ershoaib i want filliing a datagridview column without using a loop , possile ? –  Aug 28 '18 at 07:29
  • but you have to do some calculation of `result = Convert.ToInt32(src1) - Convert.ToInt32(src2);` that is from both datagridview so you must to loop through on it., If you have to just copy both of datagridview column without any calculation then it will possible too. – er-sho Aug 28 '18 at 07:32
  • @kevin73, is there any issue regarding answer. from my point of view i tried to gave you an answer that you ask question for. and your said `it works now , thank you.` but you asked some extended scenario in later comment that would be fit in new question. my suggestion is to ask new question with those extended scenario so other user will help you upon it. finally its your choice to accept or unaccept this answer. or you want more help from me let me know – er-sho Aug 28 '18 at 12:26
  • @ershoaib don't worry bro all is okay , i added new feature to my code to make color base on values , thank you again :) –  Aug 28 '18 at 15:07
  • Glad to hear, if my answer really help you then please accept it and vote up. I'd already voted up to your question :) – er-sho Aug 28 '18 at 16:50
  • If you face any issue or error while adding your new feature then post a new question and ping me url of that question here in comment then I'll definitely help you :) – er-sho Aug 28 '18 at 16:56
0

Here is a full working sample:

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();
}
Cetin Basoz
  • 15,389
  • 1
  • 22
  • 34