Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从另一个类在文本框中写入(在另一个线程上)_C#_.net_Winforms_Multithreading_Class - Fatal编程技术网

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

C# 从另一个类在文本框中写入(在另一个线程上),c#,.net,winforms,multithreading,class,C#,.net,Winforms,Multithreading,Class,我需要在程序中创建类来启动一系列事件,以便在文本框中写入文本。 我知道班级不应该知道表格。怎么做?考虑到我将在另一个线程上稳定该类 我已经尝试过创建一个接口,该接口使用ref参数连接窗体上的类和make方法 *更新:*你们都误解了我-我说的不是节目中的事件。我只需要从另一个类向textbox添加文本。我添加了“事件链”来定义simila问题,在这些问题中,他们试图从课堂上直接改变文本。很抱歉。在对应用程序了解不够的情况下,我建议您需要调用由窗体处理的类中的事件。事情是这样的: 班级有一个活动 表

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

我已经尝试过创建一个接口,该接口使用ref参数连接窗体上的类和make方法


*更新:*你们都误解了我-我说的不是节目中的事件。我只需要从另一个类向textbox添加文本。我添加了“事件链”来定义simila问题,在这些问题中,他们试图从课堂上直接改变文本。很抱歉。

在对应用程序了解不够的情况下,我建议您需要调用由窗体处理的类中的事件。事情是这样的:

  • 班级有一个活动
  • 表单启动并实例化类
  • 表单为类中的事件分配一个处理程序
  • 类执行它需要执行的任何操作,直到它达到需要与窗体通信的点为止
  • 类引发事件
  • 表单中的处理程序将被执行,文本框将发生更改
  • 因此,在类的代码中,您需要添加一些定义:

    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();
    
    以下是更详细的教程:


    在对应用程序了解不够的情况下,我建议您需要调用由窗体处理的类中的事件。事情是这样的:

  • 班级有一个活动
  • 表单启动并实例化类
  • 表单为类中的事件分配一个处理程序
  • 类执行它需要执行的任何操作,直到它达到需要与窗体通信的点为止
  • 类引发事件
  • 表单中的处理程序将被执行,文本框将发生更改
  • 因此,在类的代码中,您需要添加一些定义:

    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();
    
    以下是更详细的教程:


    这里有两种可能的选择:

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

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

    如果信息在任务“完成”时没有出现,而是通过定期间隔出现,则可以使用
    Progress
    类和
    IProgress
    界面

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

    progress.ProgressChanged += (_, data) => textBox1.Text = data;
    
    然后让另一个类接受一个
    IProgress
    实例并定期调用:

    progress.Report(someString);
    
    如果您需要
    Progress
    IProgress
    的4.5版本之前的实现,下面是一个将在.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);
            }
        }
    }
    
    公共接口程序
    {
    无效报告(T数据);
    }
    公开课进展:IProgress
    {
    同步上下文;
    公共进步()
    {
    context=SynchronizationContext.Current
    ??新的SynchronizationContext();
    }
    公共进步(行动)
    :此()
    {
    进度报告+=行动;
    }
    公共事件行动报告;
    无效进程报告(T数据)
    {
    var行动=报告的进展;
    如果(操作!=null)
    {
    Post(arg=>action((T)arg),数据);
    }
    }
    }
    
    这里有两种可能的选择:

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