【问题标题】:Cannot access a protected member control.CreateHandle()无法访问受保护的成员控件。CreateHandle()
【发布时间】:2023-03-30 22:13:01
【问题描述】:

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

我这样做是因为我使用调用方法将数据添加到 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());
}

【问题讨论】:

  • 阅读the documentation for that method,它说,“您通常不应该直接调用 CreateHandle 方法。首选方法是调用 CreateControl 方法,该方法强制为控件创建句柄创建控件时及其子控件。”.没有句柄的控件是你动态创建的吗?
  • @Rufus L,谢谢。我把链接变红了。我在我的帖子中为“else”语句添加/编辑了一些代码,其中我“CreateControl”和第二个 messageBox 应该显示创建了一个句柄。但无论如何,它大多显示 False 。有一次它确实显示了 True。这是为什么呢?
  • @Rufus。所有控件都已手动添加到表单中(拖放)。我自己不会在代码中动态创建任何控件。
  • 不要使用表单的构造函数。使用Load()Shown() 事件...
  • @Idle_Mind 我确实将所有内容都放在了 Form1_Load 事件中,但我仍然收到同样的问题:“应该创建句柄?:假”

标签: c# user-interface controls invoke


【解决方案1】:

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

这里所有的控件都得到了它们的处理。请问这是不是一个错误的方法?

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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2015-01-30
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 2014-01-26
    • 2014-02-22
    • 2015-12-30
    • 2022-01-06
    相关资源
    最近更新 更多