以另一种形式将文本发送到文本框而不创建新窗口

Posted

技术标签:

【中文标题】以另一种形式将文本发送到文本框而不创建新窗口【英文标题】:Send text to texbox in another form without making new windows 【发布时间】:2017-01-19 21:13:07 【问题描述】:

我需要制作windows窗体程序,即:

a) 显示 2 个表单,每个表单有一个文本框和一个按钮

b) 当您按下一个表单上的按钮时,程序会将该表单中的文本复制到第二个表单

c) 当您按下第二个表单上的按钮时,程序会将该表单中的文本复制到第一个表单

我尝试了几种不同的方法,却陷入了封装问题,因为这两种形式都必须在不同的实例中,对吧?我已经设法让它工作,所以每次点击时它都会在文本框中创建带有新文本的新表单实例,但是经过几个步骤后,我最终得到了充满新窗口的屏幕,我需要它在整个过程中只显示 2 个窗口运行。

【问题讨论】:

只保留第一次创建第二个窗口时的引用并继续使用它。 Interaction between forms — How to change a control of a form from another form? 【参考方案1】:

在您的Main 方法中创建窗口,但不要立即显示它们,然后通过static 属性访问它们:

public static class Program 

    public static Form1 Form1  get; private set; 
    public static Form2 Form2  get; private set; 

    public static Int32 Main(String[] args) 

        using( Program.Form1 = new Form1() )
        using( Program.Form2 = new Form2() ) 

            Application.Run( Program.Form1 ); // Form1's `Load` method would then show `Form2`
        
        Program.Form1 = Program.Form2 = null;

        return 0;
    

Form1(负责显示Form2,因为Application.Run本身只显示一个表单):

public class Form1 : Form 

    protected override void OnLoad(...) 

        Program.Form2.Show();

    

    private void Button1_Click(...) 

        Program.Form2.TextBox1.Text = this.textBox1.Text;
    

Form2(您需要通过公共属性公开其 TextBox):

public class Form2 : Form 

    public TextBox TextBox1  get  return this.textBox1;  

【讨论】:

我必须将您的描述放入默认的 Visual Studio 生成代码中,但经过一些更改后,它按预期工作。 @Ennoia 不要将您的代码放在.designer.cs 文件中,因为它们会被覆盖。有什么原因你不能把它放在非设计器文件中? 如果用户关闭Form2,然后点击Form1上的按钮发送文本怎么办? @Idle_Mind 如果Form2 在关闭后被释放,那么你会得到一个ObjectDisposedException - 你需要隐藏Form2 而不是关闭它,所以它不会被释放. ...或者您可以检查它是否已被处理并重新创建它,如我的示例中所示。只是想让用户意识到这个警告......【参考方案2】:

下面的示例展示了如何使用其构造函数将第一个表单的引用传递给第二个表单。该引用存储在类级别,以便以后使用。两个实例都使用完全相同的代码/表单:

public partial class Form1 : Form


    private Form1 target = null;

    public Form1()
    
        InitializeComponent();
        this.Text = "Instance #1";
        this.target = new Form1(this);
        this.target.Text = "Instance #2";
        this.target.Show();
    

    public Form1(Form1 target)
    
        InitializeComponent();
        this.target = target;
    

    private void button1_Click(object sender, EventArgs e)
    
        if (this.target == null || this.target.IsDisposed)
        
            this.target = new Form1(this);
            this.target.Show();
        
        this.target.textBox1.Text = this.textBox1.Text;
    


【讨论】:

【参考方案3】:

陷入封装问题,因为两种形式都必须在不同的实例中,对吧?

“封装”立即让我想到了嵌套类。典型的用例是一个不/不应该在除包含类之外的任何地方使用的类。

这个想法是允许客户端实例化Form1,但不能访问Form2 或其任何成员。如果您需要公开来自Form2 的任何内容,我建议您编写Form1 属性,以便客户端只能看到来自Form1 的所有内容。

public class Form1 : Form 
   protected Form Sibling  get; set; 

   public Form1() 
      Sibling = new Form2(this);
   

   protected override void OnLoad(...) 
      Sibling.Show();
   

    private void Button1_Click(...) 
       Sibling.TextBox1.Text = this.textBox1.Text;
    

   protected class Form2 : Form 
      protected Form Sibling  get; set; 

      public Form1 ( Form mySibling ) 
         Sibling = mySibling;
      

       private void Button1_Click(...) 
          Sibling.TextBox1.Text = this.textBox1.Text;
       
    // Form2
 // Form1

【讨论】:

以上是关于以另一种形式将文本发送到文本框而不创建新窗口的主要内容,如果未能解决你的问题,请参考以下文章

创建自动完成组合框和文本框而不区分结果 C#.net

以另一种形式运行 C# 函数

如何使用dto和C#窗口形式将信息从一种形式传输到另一种形式?

Winforms,我可以在这里使用文本框而不是组合框吗? (超过 15k 选项的下拉列表)

LibreOffice 将 PDF 转换为 Word 作为文本框而不是普通文档

将结果打印到输入框而不是URL中