C# 从另一个窗体访问按钮

C# 从另一个窗体访问按钮,c#,winforms,C#,Winforms,我有两个表单,每个表单都有按钮、文本框和标签。在form1中,我有一个按钮事件处理程序中的此代码: frmTwo form = new frmTwo (); form.Show(); this.Visible = false; //closing form 1 when frmTwo opens 我转到frmTwo的设计器文件,将所有控件:标签、文本框、按钮从private(自动生成)更改为public 在这行代码下:this.Visible=false我想放一个if语句来检查frmTw

我有两个表单,每个表单都有按钮、文本框和标签。在form1中,我有一个按钮事件处理程序中的此代码:

 frmTwo form = new frmTwo ();
 form.Show();
 this.Visible = false; //closing form 1 when frmTwo opens
我转到frmTwo的设计器文件,将所有控件:标签、文本框、按钮从private(自动生成)更改为public


在这行代码下:
this.Visible=false我想放一个if语句来检查frmTwo中的name文本框是否为空。但是当我写txtName.Text时,它会说文本框在当前上下文中不存在。我理解为什么它不存在,因为它的内部FRM不是从1开始的。但是我不确定还有什么其他方式可以访问这个文本框,因为我已经在设计器中公开了它。还有其他方法吗?

如果希望一个表单替换另一个表单,则在
表单2
.Show()
中传递对
表单1
的引用,表单将其存储在
.Owner
属性中。当第二个窗体启动时,它将隐藏第一个窗体。此外,当第二个窗体关闭时,它可以取消隐藏第一个窗体

请对
Form
等类型使用大写名称,对
mainForm=new Form()
等变量使用pascalCase

表格1.cs 表格2.cs 这是基本框架。我还添加了一些逻辑,其中
Form1
检查
Form2
中的文本框。在
Form2
中添加一个返回检查的属性:

并从1访问it表单

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

        if (f2.IsNameBlank)
        { 
            // textBox is empty.
        }
    }

扪心自问:对于form1,您想从form2中读取的信息放在文本框中是否很重要?form1真的在乎form2是否将相同的信息保存在组合框中吗

如果form1不知道form2是如何获得信息的,那不是最好的选择吗?它只需要知道form2愿意提供信息。如果form2需要从数据库中读取信息,或者从internet获取信息,form1为什么会在意呢?所有form1都想知道:“嘿Form2,给我信息X”

遗憾的是,您没有告诉我们您是否只需要此信息一次,或者在信息X发生变化时需要随时通知form1。让我们假设你是这样做的

因此,类Form2将有一个方法来提供信息X,并且它愿意告诉每个人信息X已经改变。Form2没有向外界展示它是如何获得信息的。当前版本将信息X保存在TextBox1的文本中。将来的版本可能会从组合框中读取,或者从文件或internet读取

class Form2 : System.Windows.Window
{
    public event EventHandler XChanged;

    public string X
    {
        // information X is in textBox1
        get => this.textBox1.Text;
    }

    private void TextBox1_Changed(object sender, ...)
    {
        // the text in textBox1 changed, so information X changed
        this.OnXChanged();
    }

    protected virtual void OnXChanged()
    {
        this.XChanged?.Invoke(new Eventhandler(this, EventArgs.Empty));
    }

    ... // other Form2 methods
}
现在,如果Form1想要知道X的值,它可以简单地询问:

Form2 form2 = ...
string informationX = form2.X;
如果Form1希望在信息X发生变化时随时得到通知:

form2.XChanged += InformationXChanged;

private void InformationXChanged(object sender, Eventargs e)
{
    Form2 form2 = (Form2)sender;

    // get the new information X from form2:
    string informationX = form2.X;
    this.ProcessInformationX(informationX);
}

如果form2中的文本框为空,您会怎么做?它应该是form2检查和处理的东西,真的,也许在它显示的事件中。在面向对象编程中,我们编写代码的方式并不是让代码进入到其他对象中,如果我们能帮助的话,就可以随意处理它们;它的目的是减少表格1对表格2的依赖程度;form2应该注意它自己的问题:)如果您想控制窗体上控件的可见性,最好创建一个控制它的公共方法,而不是尝试在窗体外部处理每个控件。您需要使用对您创建的窗体的引用,即“frmTwo”。所以您要使用
frmTwo.txtName.Text
。。。但是…正如其他人指出的,这没有什么价值,因为它将在表单显示后立即运行,用户将没有时间在文本框中输入任何内容。如果希望表单等待另一个表单“完成”,则很可能希望使用
ShowDialog()
而不是
Show()
来显示它。前者将导致当前表单代码停止,直到新表单被取消。建议阅读:您首先引用表单实例:
form.txtName.Text
您可以通过
Show()
本身传递引用,如
f2.Show(this),然后在Form2中,您可以通过属性访问引用。这样,您就不必创建一个单独的构造函数来接收Form1。这一点很好。我会做出改变。但是我需要钩住
OnLoad()
,以隐藏第一个表单。
Form2 form2 = ...
string informationX = form2.X;
form2.XChanged += InformationXChanged;

private void InformationXChanged(object sender, Eventargs e)
{
    Form2 form2 = (Form2)sender;

    // get the new information X from form2:
    string informationX = form2.X;
    this.ProcessInformationX(informationX);
}