1

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

我已经尝试过创建一个接口,该接口连接类并使用 ref 参数在表单上创建方法。

*更新: *你们都误解了我-我在谈论不在编程中的事件。我需要的只是将文本从另一个类添加到文本框。我添加了“事件链”来从类似问题中定义它,在它们中,他们试图直接从课堂上更改文本。对不起。

4

2 回答 2

4

这里有两种可能的选择:

“其他类”需要在“完成”工作后立即更新文本框。如果是这种情况,它不应该知道表单、任何文本框、界面,什么都没有。它应该只返回一个值并让表单使用该返回值来设置一个文本框,或者做任何事情。

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

如果在任务“完成”时信息没​​有发生,而是通过定期间隔发生,那么您可以使用Progress带有IProgress接口的类。

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

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

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

progress.Report(someString);

如果您需要 and 的 4.5 之前的实现ProgressIProgress这里有一个可以在 .NET 3.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);
        }
    }
}
于 2013-02-08T20:46:52.787 回答
2

在对您的应用程序了解不够的情况下,我会建议您需要在由表单处理的类中调用一个事件。发生的事情是这样的:

  1. 班级有活动。
  2. 表单启动并实例化类。
  3. Form 为类中的事件分配一个处理程序。
  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

于 2013-02-08T20:44:33.523 回答