用于从外部线程更改标签文本的c#通用方法

本文关键字:方法 文本 标签 从外部 线程 用于 | 更新日期: 2023-09-27 18:07:28

好的,所以这是(希望)一个相当容易的修复,但我试图创建一个通用的方法,允许外部访问标签,现在windows文档确实给出了一个例子,在这个单一的情况下

delegate void SetTextCallback(string text);
...some other code ...
private void SetText(string text)
    {
        // InvokeRequired required compares the thread ID of the
        // calling thread to the thread ID of the creating thread.
        // If these threads are different, it returns true.
        if (this.textLable.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.textLable.Text = text;
        }
    }

然而,我想创建一些更通用的东西,在那里我可以传递一些东西沿着指针的行对象,然而文本标签在windows窗体不允许这样做。对于这种情况,理想情况下,我想要一些东西沿着这些行做一些事情(这显然不会在表单中工作,只是为了解释目的)

...code...
private void SetText(string text, Label* lablePointer)
{
    if (this.lablePointer.InvokeRequired)
    {
        SetTextCallback d = new SetTextCallback(SetText);
        this.Invoke(d, new object[] { text });
    }
    else
    {
        this.lablePointer.Text = text;
    }
}

有这样做的方法吗?我一直在找,但好像哪儿都没人接。

用于从外部线程更改标签文本的c#通用方法

你不需要一个指针-你可以这样做:

private void SetText(string text, Control control)
{
    if (control.InvokeRequired)
        control.Invoke(new Action(() => control.Text = text));
    else
        control.Text = text;
}

您可以使用Control而不是Label,因为Text属性继承自Control (Label派生自Control)。这使得它更通用一些。

不需要指针,因为Label(和Control)是引用类型,这意味着当SetText()被调用时,对Label对象的引用副本被压入堆栈,这与在C/c++中传递指针的效果相似。

(我猜你是一个C/c++程序员,正在切换到c#。)

如果您需要在调用中做不止一件事,您可以调用整个函数来一次性完成所有事情:

  private void SetText(Label l, string text){
      if(l.InvokeRequired)
      {
          MethodInvoker mI = () => { 
              l.Text = text;
              //representing any other stuff you want to do in a func
              //this is just random left-over stuff from when I used it,
              //it's there to show you can do more than one thing since you are invoking a function
              lbl_Bytes_Total.Text = io.total_KB.ToString("N0");
              lbl_Uncompressed_Bytes.Text = io.mem_Used.ToString("N0");
              pgb_Load_Progress.Value = (int)pct;
          }; 
          BeginInvoke(mI);
      } 
      else
      {
          l.Text = text;
      }
  }