从另一个类(在另一个线程上)在文本框中写作

本文关键字:另一个 文本 线程 | 更新日期: 2023-09-27 17:58:19

我需要在程序中创建类来启动一系列事件,以便在文本框中写入文本。我知道这些课不应该知道表格。怎么做?考虑到我将在另一个线程上实例化该类的事实。

我已经尝试制作一个接口,用ref参数连接窗体上的类和make方法。

*更新:*你们都误解了我——我说的是节目中没有的事件。我所需要的只是将另一个类的文本添加到文本框中。我添加了"事件链"来定义类似的问题,在这些问题中,他们试图直接改变课堂上的文本。很抱歉

从另一个类(在另一个线程上)在文本框中写作

这里有两个可能的选项:

"其他类"需要在完成工作后立即更新文本框。如果是这种情况,它应该永远不知道表单、任何文本框、接口,什么都不知道。它应该只是返回一个值,并让表单使用该返回值来设置文本框,或者执行任何操作。

在大多数情况下,这是你想做的,也是解决这类问题的最简单、最有效的方法。如果不必要的话,不要使用更复杂的东西。

如果在任务"完成"时信息没有发生,而是通过周期性间隔发生,则可以将Progress类与IProgress接口一起使用。

Form创建一个实例:Progress<string> progress = new Progress<string>();。让表单为该实例附加一个事件处理程序。请注意,Progress实例将"捕获"当前同步上下文,这是一种奇特的说法,表示它在UI线程中运行。这可以这样做:

progress.ProgressChanged += (_, data) => textBox1.Text = data;

然后让另一个类接受一个IProgress<string>实例并定期调用:

progress.Report(someString);

如果您需要ProgressIProgress的4.5之前的实现,这里有一个将在.NET3.5+中编译和运行的实现:

public interface IProgress<T>
{
    void Report(T data);
}
public class Progress<T> : IProgress<T>
{
    SynchronizationContext context;
    public Progress()
    {
        context = SynchronizationContext.Current
            ?? new SynchronizationContext();
    }
    public Progress(Action<T> action)
        : this()
    {
        ProgressReported += action;
    }
    public event Action<T> ProgressReported;
    void IProgress<T>.Report(T data)
    {
        var action = ProgressReported;
        if (action != null)
        {
            context.Post(arg => action((T)arg), data);
        }
    }
}

在对应用程序了解不多的情况下,我建议您需要的是调用由表单处理的类中的事件

  1. 类有一个事件
  2. Form启动并实例化类
  3. 窗体为类中的事件分配一个处理程序
  4. 类做它需要做的任何事情,直到它达到需要与表单通信的地步
  5. 类引发事件
  6. 表单中的处理程序将被执行,并且文本框将发生更改

因此,在类的代码中,您需要添加一些定义:

public delegate void FinishedEventHandler(object sender, string ValueToReturn);
public event FinishedEventHandler Finished;

第一个是具有事件的签名的委托。按照惯例,第一个参数始终是对类本身实例的引用,其余的是要返回的值。第二个是实际事件。

现在,在处理类的函数中,我们需要在适当的时候引发事件:

void DoSomething()
{
    .
    .
    .
    if(Finished!=null) Finished(this, "some value");
}

if子句用于确保有人确实在处理我们的事件,否则我们可能会得到异常。

现在让我们来看看表单。我们需要添加一个处理事件的函数。它需要与我们前面定义的委托具有相同的签名。在这个函数中,我们根据返回的值对表单进行任何需要的更改:

private void FinishedEventHandler(object sender, string ValueToReturn)
{
    TextBox1.Text = ValueToReturn;
}

现在我们已经准备好使用我们刚刚创建的所有管道。首先我们将处理程序添加到事件中,然后我们可以调用类的处理函数。

MyClass.Finished += FinishedEventHandler;
MyClass.DoSomething();

这里有一个更详细的教程:

http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx

相关文章: