为了账号安全,请及时绑定邮箱和手机立即绑定

在 2 个表单之间发送数据

在 2 个表单之间发送数据

C#
翻阅古今 2022-06-12 11:27:54
我有带有 datagridview 和一个按钮的 form1。当我单击一个按钮时,会打开一个新表单,其中有一个文本框和一个按钮。在这个文本框中,我可以编写查询,并单击一个按钮,查询结果显示在 form1 datagridview 中。问题是它打开了 form1 的另一个实例,但我希望 form1 始终保持打开状态,并且根据 form2 中的查询输入,只有 datagridview 中的记录在发生变化。form1 和 form2 都需要在调用时打开并处于活动状态。这是我的代码://FORM 1public Form1(){    InitializeComponent();}private void button1_Click(object sender, EventArgs e){    var queryForm = new Form2();    queryForm.Show(this);}//FORM 2public 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 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

好吧,既然你在打电话Form1 frm1 = new Form1();- 你还期待opens up another instance of form1什么?- 为什么不应该new Form1()产生另一个实例?


您将需要获取已创建的Form1.


例如,请参见 在 c# windows 应用程序中查找打开的表单


当你找到它时,你可以激活它,例如:


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

    }

}

尝试以下是否足够,将上面代码中的我的注释“//读取数据”替换为:


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



查看完整回答
反对 回复 2022-06-12
?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

在 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 的传递引用来更新属性或网格。


查看完整回答
反对 回复 2022-06-12
  • 2 回答
  • 0 关注
  • 142 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信