【问题标题】:C# generic method for changing a text of a label from an outside thread.用于从外部线程更改标签文本的 C# 通用方法。
【发布时间】:2016-09-16 14:52:35
【问题描述】:

好的,所以这(希望)是一个非常简单的解决方法,但我正在尝试创建一个通用方法来允许外部访问标签,现在 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# windows forms


【解决方案1】:

您不需要指针 - 您可以这样做:

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

您可以使用Control 代替Label,因为Text 属性继承自ControlLabel 派生自Control)。这使它更加通用。

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

(我猜你是一个正在转向 C# 的 C/C++ 程序员。)

【讨论】:

  • 工作就像一个魅力,非常感谢。 (我是一名 C/Java 程序员)
【解决方案2】:

如果你需要在你的调用中做不止一件事,你可以一举调用整个函数来做所有事情:

  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;
      }
  }

【讨论】:

  • 一个调用函数的示例,以防需要同时完成一件以上的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多