从Backgroundworker DoWork访问Windows控件 [英] Access windows control from Backgroundworker DoWork

查看:92
本文介绍了从Backgroundworker DoWork访问Windows控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题如下:

我有一个Windows窗体,其中放置了一个LayoutPanel,当窗体加载时,多个控件(如:文本框和标签)被添加到LayoutPanel中.

I have a windows form in which I've placed a LayoutPanel, when the forms Loads, multiple controls like: textboxes and labels are being added to the LayoutPanel.

然后单击按钮,我需要处理用户在那些动态创建的控件上输入的数据.为此,我使用了Backgroundworker,该工具应该可以控制这些控件并读取其数据.

Then on a button click, I need to process the data entered by the user on those dynamically created controls. For that purpouse I use a Backgroundworker which is supposed to take those controls and read their data.

我的问题是Backgroundworker不允许我从DoWork方法访问控件,但是我需要这样做,因为我将报告操作进度.

My issue es that the Backgroundworker doesn't allows me to access the control from the DoWork Method, but I need to do it that way because I'll be reporting the progress of the operations.

以下是我的代码的一部分,以阐明概念:

Here are portions of my code to clarify the concept:

private void frmMyForm_Load(object sender, EventArgs e)
    {
       //I add multiple controls, this one is just for example
       LayoutPanel1.add(TextBox1);

       ....
    }

private void bgwBackground_DoWork(object sender, DoWorkEventArgs e)
    {

       foreach (Control controlOut in LayoutPanel1.Controls)
       {
           //do some stuff, this one is just for example
           string myString = controlOut.Name; //-> Here is the error, cant access controls from different Thread.
       }
    }

仅使用委托即可设置文本,但如何获取整个父控件来操纵子控件(只是为了获取信息,我不想设置任何数据,只需要获取Name,Text,东西那样).

Setting text is simple just using a delegate, but how about getting the entire parent control to manipulate the child controls (just for getting info, I don't want to set any data, just need to Get Name, Text, stuff like that).

希望我已经说清楚了,谢谢大家.

Hope I made myself clear, thank you all.

推荐答案

您只能从GUI线程访问Windows Forms控件.如果要从另一个线程操纵它们,则需要使用 Control.Invoke 方法传入委托以在GUI线程上执行.根据您的情况,您应该可以执行以下操作:

You can only access Windows Forms controls from the GUI thread. If you want to manipulate them from another thread, you will need to use the Control.Invoke method to pass in a delegate to execute on the GUI thread. In your situation, you should be able to do this:

private void bgwBackground_DoWork(object sender, DoWorkEventArgs e)
{
    foreach (Control controlOut in LayoutPanel1.Controls)
    {
        this.Invoke(new MethodInvoker(delegate {
            // Execute the following code on the GUI thread.
            string myString = controlOut.Name;
        }));
    }
}

我想定义一个扩展方法,使我可以使用更清洁的lambda语法:

I like to define an extension method that allows me to use the cleaner lambda syntax:

// Extension method.
internal static void Invoke(this Control control, Action action) {
    control.Invoke(action);
}

// Code elsewhere.
this.Invoke(() => {
    string myString = controlOut.Name;
});

这篇关于从Backgroundworker DoWork访问Windows控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆