【问题标题】:How to access a label from a thread in Windows Forms如何从 Windows 窗体中的线程访问标签
【发布时间】:2018-01-29 18:25:18
【问题描述】:

我尝试通过

访问标签
label.Text = "Some Text";

来自一个线程。但我无法访问。 我不能将标签定义为公共的,因为它在 Windows 窗体系统中。例如 Form1.cs 是包含所有程序的类,在另一个选项卡中是 Form1.css[Design]。

所以。

如何从 Form1.css 访问 Form1.css[Design] 中的标签。

PS:我还是 C# 的初学者。

这就是全部代码

using System;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;

namespace BatteryAnalyser
{
public partial class Form1 : Form
{
    Thread batteryThread = new Thread(BatteryStatusThread);
    int toogle = 0;

    public Form1()
    {
        InitializeComponent();

    }


    static int GetBatteryStatus() // THIS PART WORKS TO GET THE STATUS OF THE BATTERY
    {
        int batteryStatusValue;
        PowerStatus p = SystemInformation.PowerStatus;
        batteryStatusValue = (int)(p.BatteryLifePercent * 100);
        Debug.WriteLine("Get Battery Status Method called. Battery percentage = " + batteryStatusValue);
        return batteryStatusValue;
    } // GOOD CODE WORKS



    public static void BatteryStatusThread() //THIS IS THE THREAD THAT SHOULD UPDATE THE BATTERY PERCENTAGE IN THE LABEL VIA labelBattery.Text
    {
        Debug.WriteLine("BatteryThread entered");


        while (true)
        {
            int batteryVal = GetBatteryStatus();

            labelBattery.Text = batteryVal.ToString(); //THIS PART DOSNT RESPOND


            Thread.Sleep(1000);
        }

    }





    private void calculatingToogle_Click(object sender, EventArgs e)
    {
        //MessageBox.Show(toogle.ToString());

        labelBattery.Text = "It works from here because its a non static method";

        if (toogle == 0)
        {
            toogle = 1;
            calculatingToogle.Text = "Stop";

            try
            {
                batteryThread.Start();
                //Debug.WriteLine("Thread.Start activated");
            }
            catch (Exception exc)
            {
                //MessageBox.Show("Battery Thread start " + e.ToString());
            }

            try
            {
                batteryThread.Resume();
                //Debug.WriteLine("Thread.Resume activated");
            }
            catch (Exception exc)
            {
                //MessageBox.Show("Battery Thread Resume " + e.ToString());
            }
            return;
        }


        else if (toogle == 1) ;
        {
            toogle = 0;
            calculatingToogle.Text = "Start";

            try
            {
                batteryThread.Suspend();
                //Debug.WriteLine("Thread.Suspend activated");
            }
            catch (Exception exc)
            {
                //MessageBox.Show("Battery Thread Suspend " + e.ToString());
            }
        }
    }
}
}

我发现我无法更改标签,因为它是一个静态线程。但在非静态方法中它工作正常。我该如何解决?

【问题讨论】:

  • 查看右侧“相关”栏中的链接。
  • 不应该从另一个线程访问 WinForms 控件。设计存在根本缺陷。如何检查你是否在正确的线程上?使用Control.InvokeRequired。您可以使用Control.BeginInvokeControl.Invoke 等多种方式进行编组。

标签: c# multithreading winforms label


【解决方案1】:

你确定文件名是 Form1.css 吗?如果是这样,您正在使用层叠样式表 (CSS) 文件。在 CSS 文件中,您可以修改表单及其元素的样式。如果您在 Visual Studio 中工作,IntelliSense 不会在样式表中提示您输入表单控件名称。

如果您有一个名为 Form1.cs[Design] 的表单,则后面的代码将在 Form1.cs 中。如果您使用的是 Visual Studio,您可以输入“F7”或右键单击您的表单和“ 查看代码”以打开此文件。

在此文件中,您将能够访问您在 Form1.cs[Design] 中添加到表单的控件:

`namespace YourWindowsFormsApplication
 {
     public partial class Form1 : Form
     { 
        InitializeComponent();
        label1.Text = "Some Text";
     }
 }`

更新:

因为 BatteryStatusThread() 是一个静态方法,所以你需要创建一个 Form 的实例:

public static void BatteryStatusThread() //THIS IS THE THREAD THAT SHOULD UPDATE THE BATTERY PERCENTAGE IN THE LABEL VIA labelBattery.Text
    {
        Debug.WriteLine("BatteryThread entered");


        while (true)
        {
            int batteryVal = GetBatteryStatus();

            Form1 form = new Form1(); //Create instance here

            form.labelBattery.Text = batteryVal.ToString(); 

            Thread.Sleep(1000);
        }

    }

【讨论】:

  • 这就是我正在做的事情。但在同一类的另一个线程中。
  • 您能否发布解决方案资源管理器和/或代码的图片?
  • 我已经发布了
  • 我已经试过了,但是没有用。如果创建表单的新实例,它不会调用 labelBattery,而是在新实例中调用副本。至少我认为它是这样做的。但是感谢您帮助杰森!
【解决方案2】:

可以在静态方法参数中添加对标签的引用:

    public Form1()
    {
        InitializeComponent();
        
        StaticMethod(this.label1);

    }

    static private void StaticMethod(Label TheLabel)
    {
        TheLabel.Text = "This is from a static method";
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    相关资源
    最近更新 更多