在2种形式之间发送数据

时间:2018-12-13 12:30:46

标签: c# winforms

我有带datagridview和一个按钮的form1。当我单击一个按钮时,将打开一个新表单,其中有一个文本框和一个按钮。在此文本框中,我可以编写查询,单击按钮即可在form1 datagridview中显示查询结果。问题是,它打开了form1的另一个实例,但是根据form2中的查询输入,我希望form1始终保持打开状态,只有datagridview中的记录正在更改。调用时,form1和form2都需要打开并处于活动状态。

这是我的代码:

//FORM 1
public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    var queryForm = new Form2();
    queryForm.Show(this);
}

//FORM 2
public Form2()
{
    InitializeComponent();
}

private SqlConnection Conn;

private void Form1_Load(object sender, EventArgs e)
{
    Conn = new SqlConnection(@"Data Source=srvr;Initial Catalog =db; User ID =user; Password =pass");


}

private void btnExecute_Click(object sender, EventArgs e)
{
    Form1 frm1 = new Form1();
    frm1.Show(this);
    frm1.Activate();

    SqlCommand cmd = new SqlCommand();
    cmd.Connection = Conn;
    cmd.CommandText = txtQuery.Text;

    try
    {
        Conn.Open();

        SqlDataReader reader = cmd.ExecuteReader();

        frm1.dataGridView1.Columns.Clear();
        frm1.dataGridView1.Rows.Clear();
        if (reader.HasRows)
        {
            DataTable schema = reader.GetSchemaTable();
            int field_num = 0;
            foreach (DataRow schema_row in schema.Rows)
            {
                int col_num = frm1.dataGridView1.Columns.Add(
                    "col" + field_num.ToString(),
                    schema_row.Field<string>("ColumnName"));
                field_num++;

                frm1.dataGridView1.Columns[col_num].AutoSizeMode = 
                    DataGridViewAutoSizeColumnMode.AllCells;
            }

            object[] values = new object[reader.FieldCount];

            while (reader.Read())
            {
                reader.GetValues(values);
                frm1.dataGridView1.Rows.Add(values);
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error executing command.\n" + ex.Message);
    }
    finally
    {
        Conn.Close();
    }
}

2 个答案:

答案 0 :(得分:0)

好吧,既然您正在拨打Form1 frm1 = new Form1();-您还期望opens up another instance of form1之外还有什么? -为什么new Form1()不产生另一个实例?

您将需要获取已创建的Form1的引用。

例如看这个 Find the open forms in c# windows application

找到后,您可以激活它,例如:

var frm1 = Application.OpenForms[0];
//frm1.Show(this); <- don't need to call Show since its already open
frm1.Activate();

此外,您还应该将btnExecute_Click更改为此。

private void btnExecute_Click(object sender, EventArgs e)
{
    var frm1 = Application.OpenForms[0] as Form1; //find `Form1` like you want, I only take [0]

    //always create a new instance of SqlConnection here and dispose it with the using Keyword
    //don't use a private field to try to keep the Connection, let the internal Connection pool handle that case
    using (var con = new SqlConnection(@"Data Source=srvr;Initial Catalog =db; User ID =user; Password =pass"))
    {
        try
        {
            con.Open();

            //clean up, Command/Reader with using keyword
            using (var cmd = con.CreateCommand())
            {
                cmd.CommandText = txtQuery.Text;
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    //read data
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error executing command.\n" + ex.Message);
        }
    }

    //should activate the `Form1` AFTER the job is done, you can consider if you only want to activate it if the previous Code didn't fail
    frm1.Activate();
}

在“ read_data”例程中并没有真正得到您正在做的事情。

此代码块:

frm1.dataGridView1.Columns.Clear();
frm1.dataGridView1.Rows.Clear();
if (reader.HasRows)
{
    DataTable schema = reader.GetSchemaTable();
    int field_num = 0;
    foreach (DataRow schema_row in schema.Rows)
    {
        int col_num = frm1.dataGridView1.Columns.Add(
            "col" + field_num.ToString(),
            schema_row.Field<string>("ColumnName"));
        field_num++;

        frm1.dataGridView1.Columns[col_num].AutoSizeMode = 
            DataGridViewAutoSizeColumnMode.AllCells;
    }

    object[] values = new object[reader.FieldCount];

    while (reader.Read())
    {
        reader.GetValues(values);
        frm1.dataGridView1.Rows.Add(values);
    }
}

尝试以下条件是否足够,将上面代码中的注释“ // read data”替换为:

frm1.dataGridView1.AutoGenerateColumns = true; //say to automatically create columns, based on the result inside the datatable
frm1.dataGridView1.Columns.Clear();
var dataTable = new DataTable();
dataTable.Load(dataReader); //load the SqlDataReader into the DataTable
frm1.dataGridView1.DataSource = dataTable; //set the dataGridView's DataSource to the dataTable

答案 1 :(得分:0)

在form1上单击按钮时,您可以简单地打开form2的新实例并在那里进行工作,并在关闭时在form1中接收该值。或者,您可以通过构造函数将form1的实例传递给form2并从form2更新form1。例如:

var isFormClosed = false;
using(form1 frm = new form1())
{
   // do something here
   frm.ShowDialog();
   isFormClosed = true;
}

或者,如果您希望将form1的引用传递给form2,

var isFormClosed = false;
using(form1 frm = new form1(this))
{
   // do something here
   frm.ShowDialog();
   isFormClosed = true;
}

这里,在form2中,您可以简单地使用传递的form1引用来更新属性或网格。