Я пытаюсь заставить CreateHandles на элементах управления ВСЕ в форме, которая не сделала этого при запуске приложения.
Я делаю это, потому что я использую метод вызова для добавления данных в элементы управления пользовательского интерфейса и получаю сообщения об ошибках, что для элемента управления не создан дескриптор. Поэтому я думаю о проверке безопасности при запуске приложения и CreateHandles перед запуском любого другого кода.
Однако я получаю это сообщение об ошибке из приведенного ниже кода. В каком-то смысле я понимаю концепцию сообщения об ошибке, но не знаю, как изменить/добавить какой-либо код для этого, чтобы я мог получить доступ к элементу управления?
control.CreateHandle();
Cannot access a protected member control.CreateHandle() via a qualifier of type 'Control'; the qualifier must be of type 'Form1' (orderived from it)
Полный код:
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());
}
@ Руфус Л, спасибо. Краслю ссылку. Я добавил/отредактировал некоторый код в своем сообщении для оператора «else», где я «CreateControl» и где второй messageBox должен показывать true, что дескриптор создан. Но в основном это показывает False. Однако один раз он показал True. Почему это?
@Руфус. Все элементы управления были добавлены в форму вручную (перетаскиванием). Я не создаю никаких элементов управления динамически в коде.
Не используйте конструктор формы. Используйте события Load() или Shown()...
@Idle_Mind Я поместил все в событие Form1_Load, но все равно получаю ту же проблему: «Должен быть создан дескриптор?: False»





Я добавил логику на случай, если 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);
}
}
}
Чтение документация для этого метода, он говорит, «Обычно не следует вызывать метод CreateHandle напрямую. Предпочтительным методом является вызов метода CreateControl, который принудительно создает дескриптор для элемента управления и его дочерних элементов управления при создании элемента управления».. Являются ли элементы управления без ручек созданными вами динамически?