【问题标题】:C#: Update Label Text On Windows Forms From Console ApplicationC#:从控制台应用程序更新 Windows 窗体上的标签文本
【发布时间】:2018-02-14 00:47:34
【问题描述】:

我正在尝试更新从控制台应用程序启动的 Windows 窗体中标签内的文本,例如,我创建了此代码。

    static void Main(string[] args)
    {
        Form form = new Form();
        Label label = new Label();

        label.Text = "hi";
        form.Controls.Add(label);
        form.ShowDialog();

        Thread.Sleep(2000);

        label.Text = "bye";
        label.Invalidate();
        label.Update();
        //Refresh Doesn't work either
        //_BuyLabel.Refresh();
        Application.DoEvents();
    }

我已经完成了我的研究,但我对 Windows 窗体的了解非常有限,这方面的库已经包含在内并且不是问题。

我还需要做什么来更新文本或任何其他控制功能?

【问题讨论】:

    标签: c# winforms console label


    【解决方案1】:

    试试这个:

    class Program
    {
        private static Form form = new Form();
        private static Label label = new Label();
    
        static void Main(string[] args)
        {
            label.Text = "hi";
            form.Controls.Add(label);
    
            form.Load += Form_Load; // Add handle to load event of form
    
            form.ShowDialog();
            Application.DoEvents();
    
        }
    
        private async static void Form_Load(object sender, EventArgs e)
        {
            await Task.Run(() =>             // Run async Task for change label.Text
            {
                Thread.Sleep(2000);
                if (label.InvokeRequired)
                {
                    label.Invoke(new Action(() =>
                    {
                        label.Text = "bye";
                        label.Invalidate();
                        label.Update();
                    }));
                }
            });
        }
    }
    

    我在我的电脑上运行它,然后工作。

    【讨论】:

    • 到目前为止它对我有用,但是,整个表单没有响应,我认为它可能必须在另一个线程上完成?
    • 在 label.Text = "bye" 上引发 InvalidOperationException。这和我猜的第一个问题是同一个问题,在上面做一些测试。
    • 好的,我将再次修改答案代码,尝试在其中添加一个句柄加载事件,一个运行异步任务。
    • 请查看link
    • 从技术上讲,Task.Run 不是异步的。它创建一个新线程以完成工作,使其并发。为这么少的工作创建线程可能是个坏主意。您有压倒线程池的风险。
    【解决方案2】:

    只需添加公共函数来更改表单中的现有标签:

    public void changeLabelText(string text)
    {
       this.label1.Text=text; // label1 is the label that you want to change the text
    }
    

    在创建表单对象后从主函数调用此函数

    form.changeLabelText("text");
    

    为此,您需要创建新表单示例 MainForm

    【讨论】:

    • 你好 Elbek,这不起作用,也不能处理整个表单变得无响应。
    【解决方案3】:

    如果您只想在启动时进行自定义,这实际上非常简单;就像您想要自定义的任何其他对象一样,给它一个构造函数,该构造函数接受您想要用来自定义类行为的任何参数。比如,在你的情况下,标签文本。

    这里不需要线程或通信。从外部来源设置该标签是完全没有必要的。只需提前设计表单类,标签已经在它上面,并给它一个自定义构造函数,该构造函数接受要放在该标签上的字符串。

    static void Main(string[] args)
    {
        MyForm form = new MyForm("hi");
        form.ShowDialog();
    }
    

    MyForm 类本身中:

    public MyForm(string labelText)
    {
        // Generated code.
        InitializeComponent();
        // Set label text
        this.lblInfo.Text = labelText;
    }
    

    顺便说一句...我不确定您是否清楚“控制台应用程序”到底是什么。 任何程序都可以从命令提示符启动,并且完全可以为 Windows 应用程序提供 static void Main(String[] args) 构造函数以使其接受命令行参数,事实上,与任何其他应用程序一样,您可以将Main 函数的返回类型更改为int,使其在完成运行后返回exit code。但是,控制台应用程序通常很少使用来显示表单。这通常违背了控制台应用程序的目的。

    【讨论】:

    • 我以控制台应用为例,因为我打算将我的代码附加到第三方软件上,他们提供的 API 有限,但我可以使用 Windows 窗体,这不像使用 Visual Studio并设置一个 Windows 窗体项目,我能够让一些窗口在其中工作,但在这种情况下它没有更新,我一直在试图知道为什么。将尝试您的解决方案,感谢您的帮助。
    【解决方案4】:

    更新:


    您需要创建一个线程来运行表单并允许更新标签或其他表单方法。创建一个包含表单的类。

    更新您的代码以遵循以下类似示例。主要要点是线程创建和 DoWork() 方法。您必须在其自己的线程中运行表单,否则它将被阻止。创建继承自 :Form 的 MyForm 类,并添加一个 updateLabel 函数,您可以在创建线程后在 DoWork 方法中调用该函数。

    您得到的错误来自 Application.SetCompatibleTextRenderingDefault(false); .你可以把它拿出来。


    static void Main(string[] args)
    {
            Console.WriteLine("Press return to launch the form.");
            Console.ReadLine();
    
            Application.EnableVisualStyles();
    
    
            MyForm testForm = new MyForm();
    
            System.Threading.Thread worker = new System.Threading.Thread(DoWork);
            worker.Start(testForm);
    
            Application.Run(testForm);
        }
    
        private static void DoWork(object formObject)
        {
            MyForm form = formObject as MyForm;
    
            for (int i=0; i<=30; ++i)
            {
                form.UpdateLabel(i.ToString());
                System.Threading.Thread.Sleep(1000);
            }
        }
    

    【讨论】:

    • 获得了 System.InvalidOperationException pm UpdateTextBox 方法。目前正在尝试修复它,如果我错过了其他东西,请告诉我。感谢您的帮助。
    • 当您单步执行代码时,错误发生在哪里?您需要在您的类中创建 UpdateTextBox(String x) 方法才能使其工作。
    • 这就是我首先做的,例外是在方法中,就在:Form.Text = text;
    • 我认为这与使调用线程安全有关,就像在 VS 提供的这个链接中一样,我正在尝试使用 backgroundworker
    • 我能够在 linqpad 中无错误地运行代码。你从哪里调用 Form.text ?它应该在您的表单类和您提供给 dowork 线程的方法中。即 myformclass.updateText() ....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多