简体   繁体   English

在 C# 中从另一个线程向 Controls 属性添加控件

[英]Add a control to Controls property from another thread in C#

I need to add a new control to a control from a background worker in c#. I tried to use Type.InvokeMember() , but I alway get an error.我需要向 c# 的后台工作人员的控件添加一个新控件。我尝试使用Type.InvokeMember() ,但我总是出错。 That´s my code:那是我的代码:

private delegate void AddControlThreadSafeDelegate(Control newControl, Control parent);

public static void AddControlThreadSafe(Control newControl, Control parent)
{
    if (newControl == null) return;
    if (parent == null) return;

    if (parent.InvokeRequired)
    {
        parent.Invoke(new AddControlThreadSafeDelegate(AddControlThreadSafe),
            new object[] { newControl, parent });
    }
    else
    {
        parent.GetType().InvokeMember("Controls.Add", BindingFlags.InvokeMethod, null, parent, new object[] { newControl });
    }
}

The error is错误是

The method "System.Windows.Forms.FlowLayoutPanel.Controls.Add" could not be found找不到方法“System.Windows.Forms.FlowLayoutPanel.Controls.Add”

I don´t get an error if I instead invoke "Hide".如果我改为调用“隐藏”,我不会收到错误消息。 It seems like it doesn´t work, because the method doesn´t belong directly to the parent but to one of it´s propertys.它似乎不起作用,因为该方法不直接属于父级,而是属于它的一个属性。 Does anyone know how to fix this or another way to do it?有谁知道如何解决这个问题或其他方法吗?

You do not need to do the Cermony with creating a delegate etc. You could just use a lambda:您不需要通过创建委托等来执行 Cermony。您可以只使用 lambda:

parent.Invoke(() => parent.Controls.Add(newControl));

In older versions of .net you may need an explicit cast:在 .net 的旧版本中,您可能需要显式转换:

parent.Invoke((Action)(() => parent.Controls.Add(newControl)));

Also, if you are already on the UI thread you do not have to mess around with InvokeMember , just call:此外,如果您已经在 UI 线程上,则不必乱用InvokeMember ,只需调用:

parent.Controls.Add(newControl);

Note that background worker is mostly superseded by Task and async/await, so modern code should look something like this:请注意,后台 worker 大部分已被 Task 和 async/await 取代,因此现代代码应如下所示:

// gather parameters from the UI
var result = await Task.Run(() => MyBackgroundMethod(myParameter));
// Update UI with the results

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM