1
votes

I'm making a program where I have a DataGridView. This GridView gets its data through 1 table through an SQL connection. This table has 1 column and some rows.

For every row, there's another column with buttons. When I click the button, I want it to open another form, which just displays the name of the file in the row I clicked for now.

Unfortunately, the program opens the form, but shows the first cell from the table. This is because Form2 is never informed of the e.RowIndex number it should be getting from Form1, so that it knows which row to show. So now it assumes that whichever button I click, I want e.RowIndex number 0, which refers to cell number 1.

So, on to the question; How do I make it update my chartRowNumber before it assumes that it's just 0?

Form 1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Threading;

namespace WindowsFormsApplication5
{
    public partial class Form1 : Form
    {![enter image description here][1]
    DataTable userTable = new DataTable();
    DataGridViewButtonColumn checkMeasurement = new DataGridViewButtonColumn();
    public DataSet ds = new DataSet();
    private SqlConnection con = new SqlConnection(@"Data Source=irrelevant");
    public Form1()
    {
        InitializeComponent();
        con.Open();
        SqlCommand cmd = new SqlCommand("SELECT BlobFilename FROM tblUsers", con);
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        da.Fill(ds);
        checkMeasurement.HeaderText = "Se Måling";
        checkMeasurement.Text = "";
        checkMeasurement.UseColumnTextForButtonValue = true;
        dataGridView1.DataSource = ds.Tables[0];
        dataGridView1.Columns.Add(checkMeasurement);
    }

    public void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == 0)
        {
            Form2 f = new Form2();
            f.chartRowNumber = e.RowIndex;
            Thread.Sleep(1000);
            f.Show();
        }
    }
}

}

Form 2

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication5
{
    public partial class Form2 : Form
    {
        public int chartRowNumber;
        public Form2()
        {
            InitializeComponent();
            Form1 f = new Form1();
            DataTable PatientTable = f.ds.Tables[0];
            listBox1.Items.Add(PatientTable.Rows[chartRowNumber].ItemArray[0].ToString());
        }
    }
}

Here's a picture of the GUI if you're interested. http://i.stack.imgur.com/PDyFt.png

2

2 Answers

1
votes

Create an overloaded constructor for Form2 that takes in the row number

public int chartRowNumber = 0;
    public Form2()
    {
        InitializeComponent();
        Form1 f = new Form1();
        DataTable PatientTable = f.ds.Tables[0];
        listBox1.Items.Add(PatientTable.Rows[chartRowNumber].ItemArray[0].ToString());
    }

public Form2(int rowIndex)
    {
        InitializeComponent();
        Form1 f = new Form1();
        DataTable PatientTable = f.ds.Tables[rowIndex];
        listBox1.Items.Add(PatientTable.Rows[chartRowNumber].ItemArray[0].ToString());
    }

You will have to check this indexing as I am not sure where you want to use the rowIndex variable but you can use this method to get it to the Form2 instance

0
votes

Your code cannot work for two reasons. The first one is because the constructor of Form2 runs before you pass the rowIndex, the second reason is because you build another instance of Form1 to extract the datatable. This second instance has its own gridview and the constructor of Form1 requery the database and fills the gridview of this second form1 instance. In this instance the event dataGridView1_CellContentClick never fires and you don't have any rowIndex different from zero

In the CellContentClick event you need to pass to the Form2 constructor both the rowIndex and the table needed inside the constructor

public void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 0)
    {
        Form2 f = new Form2(e.RowIndex, ds.Tables[0]);
        f.Show();
    }
}

and in the Form2 constructor you use the two variables passed from the current instance of Form1 without building another instance

public partial class Form2 : Form
{
    public Form2(int chartRowNumber, DataTable form1Table)
    {
        InitializeComponent();
        listBox1.Items.Add(form1Table.Rows[chartRowNumber].ItemArray[0].ToString());
    }
}

Of course, if you need to keep these variables for other operations you should save them in global variables inside the current instance of Form2

Instead, if, inside the form2, you don't need neither the rowNumber and the datatable, then you could just pass the element zero of the item array directly from the current instance of Form1

public void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 0)
    {
        Form2 f = new Form2(ds.Tables[0].Rows[e.RowIndex][0].ToString());
        f.Show();
    }
}

public partial class Form2 : Form
{
    public Form2(string item)
    {
        InitializeComponent();
        listBox1.Items.Add(item);
    }
}