首页 > 解决方案 > 无法访问受保护的成员控件。CreateHandle()

问题描述

我试图在启动应用程序时强制在表单上的所有控件上创建句柄。

我这样做是因为我使用调用方法将数据添加到 UI 控件并且我收到错误消息,表明没有为控件创建句柄。因此,我正在考虑在运行任何其他代码之前启动应用程序和 CreateHandles 时进行安全检查。

但是,我确实从以下代码中收到了此错误消息。在某种程度上,我理解错误消息的概念,但不知道如何为此更改/添加任何代码,以便我可以访问控件?

control.CreateHandle();

无法通过“Control”类型的限定符访问受保护的成员 control.CreateHandle();限定符必须是“Form1”类型(或派生自它)

完整代码:

public Form1()
{
    InitializeComponent();
    Thread thread = new Thread(() => EnumerateChildren(this)); thread.IsBackground = true; thread.Start();
}
public void EnumerateChildren(Control root)
{
    foreach (Control control in root.Controls)
    {
        if (control.IsHandleCreated)
        {
            //Handle is already created
        }
        else
        {
            //Force to Create a handle but gives this error:
            //Cannot access a protected member control.CreateHandle() via a qualifier of type 'Control'; the qualifier must be of type 'Form1' (orderived from it)
            control.CreateHandle();
        }
        if (control.Controls != null)
        {
            EnumerateChildren(control);
        }
    }
}

我测试在“else”语句中添加以下代码,其中第二个消息框应该显示“True”,但这并不总是发生?

else
{
    //Force to Create a handle but gives this error:
    //Cannot access a protected member control.CreateHandle() via a qualifier of type 'Control'; the qualifier must be of type 'Form1' (orderived from it)
    MessageBox.Show("Handle is not created: " + control.IsHandleCreated.ToString());
    control.CreateControl();
    MessageBox.Show("Handle should be created?: " + control.IsHandleCreated.ToString());
}

标签: c#user-interfacecontrolsinvoke

解决方案


如果 CreateControl() 没有成功创建句柄,我确实添加了逻辑。我直接 createHandle() 并且所有控件现在都显示为真,这意味着它似乎可以工作。

在这里,所有控件都得到了处理。请告诉这是否是错误的方法?

public void EnumerateChildren(Control root)
{
    foreach (Control control in root.Controls)
    {
        if (control.IsHandleCreated)
        {
            //Handle is already created
        }
        else
        {
            control.CreateControl();
            if (control.IsHandleCreated == false)
            {
                //The access the handle directly
                MethodInfo ch = control.GetType().GetMethod("CreateHandle", BindingFlags.NonPublic | BindingFlags.Instance);
                Invoke((System.Windows.Forms.MethodInvoker)delegate { ch.Invoke(control, new object[0]); });
            }
        }
        if (control.Controls != null)
        {
            EnumerateChildren(control);
        }
    }
}

推荐阅读