我有带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();
}
}
答案 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引用来更新属性或网格。