【问题标题】:Why can't I interact with form objects from within the main program?为什么我不能在主程序中与表单对象进行交互?
【发布时间】:2017-10-06 17:55:05
【问题描述】:

这应该很简单,但我很难看到任何结果。

我的表单代码如下:

//Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NotepadRW
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected TextBox textReadInfo;
        public void SetReadInfo(String str)
        {
            txtReadInfo.Text = str;
        }
    }
}

我还有以下程序代码:

//Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NotepadRW
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 form1 = new Form1();
            Application.Run(form1);

            form1.SetReadInfo("Hi");

        }
    }
}

结果如下:

为什么不显示我提供的字符串?我是否没有正确理解该程序如何与 Windows 窗体一起工作?调用 Form1 的新实例时,Program.cs 的 Main() 方法的执行是否停止?

注意:我已经尝试过使用文本框和富文本框。结果相同。

加分: 我是否正确遵循封装?我打算将文本框修改为可公开访问(这将起作用),但我认为这是“正确”的做法。

【问题讨论】:

  • txtReadInfo.Text = str 是拼写错误还是 txtReadInfo 定义在我们看不到的地方?
  • InitializeComponent 通话后为什么不做this.SetReadInfo("Hi")
  • 您将在 Application.Run 之后分配该文本。这将启动 GUI 事件循环并且在主窗体关闭之前不会退出。在表单构造函数和应用程序运行之间移动这条线。

标签: c# winforms


【解决方案1】:

虽然从 the documentation 中看不出来,但 Application.Run(Form) 方法会阻塞。您可以从以下引用中推断出这一点:

Form类的Dispose方法会在该方法返回之前被调用。

这意味着表单将完成它的工作,并且必须在 Run 返回之前完成它的工作。即,它会阻塞。

你可以通过切换顺序来完成你想要的。而不是

Form1 form1 = new Form1();
Application.Run(form1);
form1.SetReadInfo("Hi");

试试

Form1 form1 = new Form1();
form1.SetReadInfo("Hi");
Application.Run(form1);

【讨论】:

  • 正是我在说以下"Does execution of the Main() method of Program.cs stop when the new instance of Form1 is called?"时的想法所以program.cs除了运行表单本身之外就没用了吗?我的大部分工作是否应该在大多数程序的 Form1.cs 代码中完成? (尽可能简单,包括这个)
  • 取决于应用程序。对于一个简单的 Windows 窗体应用程序,是的,将所有内容都放在主窗体中可能是最简单的,因为 UX 将以窗体为中心。如果您希望一开始就有多个线程,或者如果您的应用程序缺少“主”表单,那么您会更多地使用应用程序类。
  • 你大大提高了我对这一点的理解。我非常感谢您快速而详尽的回复。
【解决方案2】:

您不应该公开您的文本框,否则您可能会遇到跨线程执行异常。

您的代码不起作用的原因是因为您在主线程上运行表单,因此 Application.Run() 之后的任何内容都不会被执行。您可以在单独的线程上运行表单。

Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 form = new Form1();

            System.Threading.Thread workerThread = new System.Threading.Thread(() => Application.Run(form));

            workerThread.Start();

            form.SetReadInfo("Hello");

【讨论】:

  • 这是一个绝妙的技巧,将来对我很有用。我很确定。由于这是一个单线程应用程序,需要最少的计算能力,因此我选择了 John 对这个问题的回答。但是,一旦我进入多线程应用程序,您的回答将成为我的起点。谢谢。
猜你喜欢
  • 2012-10-30
  • 2020-08-21
  • 1970-01-01
  • 2021-10-09
  • 2017-11-27
  • 2012-02-09
  • 2020-07-27
  • 2022-11-02
  • 1970-01-01
相关资源
最近更新 更多