C# 使用相同的表单
C# Using Same Form
当我们使用以下代码同时打开 FormA 和 FormB 或其他程序时,我遇到了问题。代码:
namespace form_sample
{
public partial class Form1 : Form
{
public Form SampleForm;
public Form1()
{
InitializeComponent();
}
private void CreateForm()
{
SampleForm = new Form();
SampleForm.Name = "formname";
SampleForm.Text = "Form Caption";
SampleForm.Show();
SampleForm.Shown += new EventHandler(SampleForm_Shown);
}
private void SampleForm_Shown(object sender, EventArgs e)
{
GetElements();
GetButtons();
}
private void GetElements()
{
TextBox textdata = new TextBox();
textdata.Name = "TextData";
textdata.Width = 200;
textdata.Height = 50;
textdata.Location = new Point(20, 20);
SampleForm.Controls.Add(textdata);
}
private void GetButtons()
{
Button ShowMsg = new Button();
ShowMsg.Name = "ShowMsg";
ShowMsg.Text = "Show TextBox Message";
ShowMsg.Width = 100;
ShowMsg.Location = new Point(100, 100);
SampleForm.Controls.Add(ShowMsg);
ShowMsg.Click += new EventHandler(ShowMsg_click);
}
private void ShowMsg_click (object sender, EventArgs e)
{
foreach (Control elements in SampleForm.Controls)
{
if (elements.GetType() == typeof(TextBox))
{
MessageBox.Show(elements.Text.ToString());
}
}
}
private void FormA_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormB_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormC_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormD_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormE_Click(object sender, EventArgs e)
{
CreateForm();
}
}
}
例如:FormA、FormB 和 FormC 已打开。我想显示 FormC 的 TextBox 消息。
谢谢。
您仅持有对 一个 表格的引用:
public Form SampleForm;
每次创建新表格时,您都会继续覆盖该引用:
SampleForm = new Form();
因此,无论何时制作新表格,您都无法再访问以前的表格。它们仍然开放,但此代码不包含对它们的引用。
有许多不同的方法可以解决这个问题并构建您的代码。 最简单 和最直接的方法是与代码的其余部分保持一致。请注意,您的 ret 代码明确采用一组有限的特定形式:
private void FormA_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormB_Click(object sender, EventArgs e)
{
CreateForm();
}
// etc...
因此,您最好坚持使用该模式,至少暂时如此才能使其正常工作。 (稍后重构。)为此,创建一组有限的变量来保存对表单的引用:
public Form SampleFormA;
public Form SampleFormB;
public Form SampleFormC;
public Form SampleFormD;
public Form SampleFormE;
然后修改您的函数以接受对正在创建的表单的引用:
private void CreateForm(Form form)
{
form = new Form();
form.Name = "formname";
form.Text = "Form Caption";
form.Show();
form.Shown += new EventHandler(SampleForm_Shown);
}
并将该引用添加到该函数的调用中:
private void FormA_Click(object sender, EventArgs e)
{
CreateForm(SampleFormA);
}
// etc.
(现在我确定您可以开始看到所有这些重复代码中出现的模式。这是您开始考虑重构的地方。我有意将其作为练习供您考虑并仅关注手头错误的原因。但让我们先完成它的工作...)
经过同样的努力,您的其他函数也将需要参考他们想要的特定形式:
private void GetElements(Form form)
{
// use the function variable instead of the class variable
}
private void GetButtons(Form form)
{
// use the function variable instead of the class variable
}
要提供对这些函数的引用,请使用事件处理程序可用的对象:
private void SampleForm_Shown(object sender, EventArgs e)
{
GetElements(sender as Form);
GetButtons(sender as Form);
}
你当然可以在那里进行一些错误检查,以确保 sender
确实是 Form
的一个实例,系统状态中没有其他错误等。但是这个 应该至少让你继续。
您的其他活动可能需要类似的更改。
归根结底,问题是您正试图从一个变量开始做所有事情。但是您有多个表单实例。所以你需要所有变量的变量(或 collection/array/etc. 在单个变量中......记得考虑重构以删除重复的代码)并且作用于它们的函数需要更加动态,而不是全部作用于单个变量。
public Form SampleForm;
private void CreateForm()
{
SampleForm = new Form();
...
}
每次调用 CreateForm() 时,您将失去获取之前存储在该变量中的表单的能力。
一个简单的更正是使用这样的模式
public List<Form> SampleForms = new List<Form>();
private void CreateForm()
{
var form = new Form();
SampleForms.Add(form);
...
}
//use this to get a form from the collection. Form.ID, Form.Text
private Form GetForm(string formName)
{
return SampleForms.FirstOrDefault(f => f.ID.Equals(formName));
}
您的 SampleForm
字段始终包含您创建的最后一个表单,这就是为什么在事件中使用它会产生不正确的行为。
要解决此问题,请先从 Form1
class 中删除 SampleForm
字段。然后使用您的方法的以下修改版本:
private static void CreateForm()
{
var SampleForm = new Form();
SampleForm.Name = "formname";
SampleForm.Text = "Form Caption";
SampleForm.Show();
SampleForm.Shown += new EventHandler(SampleForm_Shown);
}
private static void SampleForm_Shown(object sender, EventArgs e)
{
var SampleForm = (Form)sender;
GetElements(SampleForm);
GetButtons(SampleForm);
}
private static void GetElements(Form SampleForm)
{
TextBox textdata = new TextBox();
textdata.Name = "TextData";
textdata.Width = 200;
textdata.Height = 50;
textdata.Location = new Point(20, 20);
SampleForm.Controls.Add(textdata);
}
private static void GetButtons(Form SampleForm)
{
Button ShowMsg = new Button();
ShowMsg.Name = "ShowMsg";
ShowMsg.Text = "Show TextBox Message";
ShowMsg.Width = 100;
ShowMsg.Location = new Point(100, 100);
SampleForm.Controls.Add(ShowMsg);
ShowMsg.Click += new EventHandler(ShowMsg_click);
}
private static void ShowMsg_click (object sender, EventArgs e)
{
var ShowMsg = (Button)sender;
var SampleForm = ShowMsg.FindForm();
foreach (Control elements in SampleForm.Controls)
{
if (elements.GetType() == typeof(TextBox))
{
MessageBox.Show(elements.Text.ToString());
}
}
}
请注意,我已经制作了所有这些方法static
,因此无法在引用共享变量时出错。为了让事情更容易理解,我保留了你的名字,尽管他们没有遵循推荐的 C# 命名约定。
当我们使用以下代码同时打开 FormA 和 FormB 或其他程序时,我遇到了问题。代码:
namespace form_sample
{
public partial class Form1 : Form
{
public Form SampleForm;
public Form1()
{
InitializeComponent();
}
private void CreateForm()
{
SampleForm = new Form();
SampleForm.Name = "formname";
SampleForm.Text = "Form Caption";
SampleForm.Show();
SampleForm.Shown += new EventHandler(SampleForm_Shown);
}
private void SampleForm_Shown(object sender, EventArgs e)
{
GetElements();
GetButtons();
}
private void GetElements()
{
TextBox textdata = new TextBox();
textdata.Name = "TextData";
textdata.Width = 200;
textdata.Height = 50;
textdata.Location = new Point(20, 20);
SampleForm.Controls.Add(textdata);
}
private void GetButtons()
{
Button ShowMsg = new Button();
ShowMsg.Name = "ShowMsg";
ShowMsg.Text = "Show TextBox Message";
ShowMsg.Width = 100;
ShowMsg.Location = new Point(100, 100);
SampleForm.Controls.Add(ShowMsg);
ShowMsg.Click += new EventHandler(ShowMsg_click);
}
private void ShowMsg_click (object sender, EventArgs e)
{
foreach (Control elements in SampleForm.Controls)
{
if (elements.GetType() == typeof(TextBox))
{
MessageBox.Show(elements.Text.ToString());
}
}
}
private void FormA_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormB_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormC_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormD_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormE_Click(object sender, EventArgs e)
{
CreateForm();
}
}
}
例如:FormA、FormB 和 FormC 已打开。我想显示 FormC 的 TextBox 消息。
谢谢。
您仅持有对 一个 表格的引用:
public Form SampleForm;
每次创建新表格时,您都会继续覆盖该引用:
SampleForm = new Form();
因此,无论何时制作新表格,您都无法再访问以前的表格。它们仍然开放,但此代码不包含对它们的引用。
有许多不同的方法可以解决这个问题并构建您的代码。 最简单 和最直接的方法是与代码的其余部分保持一致。请注意,您的 ret 代码明确采用一组有限的特定形式:
private void FormA_Click(object sender, EventArgs e)
{
CreateForm();
}
private void FormB_Click(object sender, EventArgs e)
{
CreateForm();
}
// etc...
因此,您最好坚持使用该模式,至少暂时如此才能使其正常工作。 (稍后重构。)为此,创建一组有限的变量来保存对表单的引用:
public Form SampleFormA;
public Form SampleFormB;
public Form SampleFormC;
public Form SampleFormD;
public Form SampleFormE;
然后修改您的函数以接受对正在创建的表单的引用:
private void CreateForm(Form form)
{
form = new Form();
form.Name = "formname";
form.Text = "Form Caption";
form.Show();
form.Shown += new EventHandler(SampleForm_Shown);
}
并将该引用添加到该函数的调用中:
private void FormA_Click(object sender, EventArgs e)
{
CreateForm(SampleFormA);
}
// etc.
(现在我确定您可以开始看到所有这些重复代码中出现的模式。这是您开始考虑重构的地方。我有意将其作为练习供您考虑并仅关注手头错误的原因。但让我们先完成它的工作...)
经过同样的努力,您的其他函数也将需要参考他们想要的特定形式:
private void GetElements(Form form)
{
// use the function variable instead of the class variable
}
private void GetButtons(Form form)
{
// use the function variable instead of the class variable
}
要提供对这些函数的引用,请使用事件处理程序可用的对象:
private void SampleForm_Shown(object sender, EventArgs e)
{
GetElements(sender as Form);
GetButtons(sender as Form);
}
你当然可以在那里进行一些错误检查,以确保 sender
确实是 Form
的一个实例,系统状态中没有其他错误等。但是这个 应该至少让你继续。
您的其他活动可能需要类似的更改。
归根结底,问题是您正试图从一个变量开始做所有事情。但是您有多个表单实例。所以你需要所有变量的变量(或 collection/array/etc. 在单个变量中......记得考虑重构以删除重复的代码)并且作用于它们的函数需要更加动态,而不是全部作用于单个变量。
public Form SampleForm;
private void CreateForm()
{
SampleForm = new Form();
...
}
每次调用 CreateForm() 时,您将失去获取之前存储在该变量中的表单的能力。
一个简单的更正是使用这样的模式
public List<Form> SampleForms = new List<Form>();
private void CreateForm()
{
var form = new Form();
SampleForms.Add(form);
...
}
//use this to get a form from the collection. Form.ID, Form.Text
private Form GetForm(string formName)
{
return SampleForms.FirstOrDefault(f => f.ID.Equals(formName));
}
您的 SampleForm
字段始终包含您创建的最后一个表单,这就是为什么在事件中使用它会产生不正确的行为。
要解决此问题,请先从 Form1
class 中删除 SampleForm
字段。然后使用您的方法的以下修改版本:
private static void CreateForm()
{
var SampleForm = new Form();
SampleForm.Name = "formname";
SampleForm.Text = "Form Caption";
SampleForm.Show();
SampleForm.Shown += new EventHandler(SampleForm_Shown);
}
private static void SampleForm_Shown(object sender, EventArgs e)
{
var SampleForm = (Form)sender;
GetElements(SampleForm);
GetButtons(SampleForm);
}
private static void GetElements(Form SampleForm)
{
TextBox textdata = new TextBox();
textdata.Name = "TextData";
textdata.Width = 200;
textdata.Height = 50;
textdata.Location = new Point(20, 20);
SampleForm.Controls.Add(textdata);
}
private static void GetButtons(Form SampleForm)
{
Button ShowMsg = new Button();
ShowMsg.Name = "ShowMsg";
ShowMsg.Text = "Show TextBox Message";
ShowMsg.Width = 100;
ShowMsg.Location = new Point(100, 100);
SampleForm.Controls.Add(ShowMsg);
ShowMsg.Click += new EventHandler(ShowMsg_click);
}
private static void ShowMsg_click (object sender, EventArgs e)
{
var ShowMsg = (Button)sender;
var SampleForm = ShowMsg.FindForm();
foreach (Control elements in SampleForm.Controls)
{
if (elements.GetType() == typeof(TextBox))
{
MessageBox.Show(elements.Text.ToString());
}
}
}
请注意,我已经制作了所有这些方法static
,因此无法在引用共享变量时出错。为了让事情更容易理解,我保留了你的名字,尽管他们没有遵循推荐的 C# 命名约定。