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# 命名约定。