2013-11-28 6 views
0

Я создал Form с загрузкой Panel на нем. Идея состоит в том, что я хочу показать эту панель загрузки, пока мой динамически созданный элемент управления не будет готов к отображению.Запретить управление winforms стать видимым при динамическом добавлении коллекции Controls

Сначала отображается изображение Panel, а затем во время события OnShown я создаю свой элемент управления и добавлю его на страницу. Причина, по которой я использую OnShown, заключается в том, что Form используется в сценарии Mdi, поэтому мне нужно, чтобы он был полностью отображен, прежде чем я начну загрузку элемента управления (если я попробую это в событии Load, то вкладка Mdi не будет отображаться, пока мой контроль загружен).

Проблема заключается в том, что существует заметное мерцание, которое я считаю, это связано с тем, что, когда я добавить свой контроль в Controls коллекции:

а) Видимое свойство немедленно установить в действительности. b) мой элемент управления, кажется, появляется перед панелью загрузки, даже если индекс z выглядит правильно.

Вот суть вопроса

protected override void OnShown(EventArgs e) 
    { 
     Debug.WriteLine(loadingPanel.Visible); //true 
     Debug.WriteLine(Controls.GetChildIndex(loadingPanel)); //0 

     Debug.WriteLine(myControl.Visible); //false 

     myControl.Visible = false; 
     Controls.Add(myControl); 
     //** 

     Debug.WriteLine(myControl.Visible); //true 

     Debug.WriteLine(Controls.GetChildIndex(loadingPanel)); //0 
     Debug.WriteLine(Controls.GetChildIndex(myControl)); //1 

     Debug.WriteLine(loadingPanel.Visible); //true 

     base.OnShown(e); 
    } 

Я надеялся, что я мог бы добавить свой контроль в коллекцию и она будет оставаться Visible = false так, чтобы я мог установить Visible = true когда событие Load моего элемент управления было завершено. Вместо этого мой контроль появляется, и я становлюсь мерцающим. Интересно, что если я не установил loadingPanel.Visible = false в любой момент, то, как только мой контроль завершит загрузку, загрузочная панель снова появится и скрывает мой контроль.

Любые идеи?

+0

Вы можете переопределить метод рисования и установить флаг в свой метод «OnShown», пропуская любые операции с краской до завершения добавления. Просто удар в темноте! – Charleh

+0

@Charleh вы могли бы разработать еще кое-что, похоже, что это может быть что-то стоящее попробовать?Может быть, в ответ? – OffHeGoes

ответ

0

Несколько странно, это, как мне удалось решить мою проблему:

protected override void OnShown(EventArgs e) 
{ 
    //trigger the OnLoad event of myControl - this does NOT cause it to appear 
    //over the loading Panel 
    myControl.Visible = true; 
    myControl.Visible = false; //set it back to hidden 

    //now add the control to the Controls collection - this now does NOT trigger the 
    //change to Visible, therefore leaving it hidden 
    Controls.Add(myControl); 

    //finally, set it to Visible to actually show it 
    myControl.Visible = true; 

    base.OnShown(e); 
} 

Я могу только предположить, что при добавлении элемента управления к коллекции Control затем, если ручка не создан, он будет автоматически установить его Видимый. Сделав его видимым перед добавлением его в коллекцию, соответствующие дескрипторы создаются, не влияя на родительский элемент управления. Затем, когда он добавляется в коллекцию позже, он все равно не мешает родительскому элементу управления.

0

Я принимаю его mycontrol является стандартным управлением winforms? Почему бы не создать настраиваемый элемент управления с нужным mycontrol в нем, и в этом настраиваемом элементе управления значение видимого свойства элемента управления дочернего элемента будет false?

Не проверял это, но вот что я буду делать дальше ...?

+0

Извините, я должен был сказать, что мой контроль - это пользовательский UserControl. Я полагаю, что ваше предложение ничего не изменит, поскольку Controls.Add просто установит свойство Visible в true. – OffHeGoes

+0

Да, но по умолчанию ваши «дочерние» элементы управления видны = false? Не «устанавливать» его видимым = false только до его загрузки, имеют ли дочерние элементы управления visible = false по умолчанию? И установите их в visible = true позже? –

0

Вам не нужно менять Visible таким образом, даже если вы установите его на false успешно, когда вы их покажете, есть еще некоторое мерцание, если количество элементов управления велико. Вы должны переопределить метод OnLoad и использовать SuspendLayout и ResumeLayout вроде этого:

//Start adding controls 
SuspendLayout(); 
//.... 

//in the OnLoad 
protected override void OnLoad(EventArgs e){ 
    ResumeLayout(true); 
} 

Я сомневаюсь, что с помощью ResumeLayout(true) сразу после окончания добавления элементов управления может быть в порядке, вы также должны попробовать.