2016-12-10 4 views
0

У меня есть форма mainwindow, которая действует как форма mdi. Когда пользователь выбирает опцию из меню, mainwindow будет загружать UserControl для отображения.Убедитесь, что UserControl полностью выполнил рисование перед запуском метода

Private Sub treNavTree_NodeMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles treNavTree.NodeMouseClick 

Dim nextDisplay As UserControl = GetUserControl(e.Node.Text) 
If nextDisplay Is Nothing Then Exit Sub 

pnlMain.Controls.Remove(currentDisplay) 
currentDisplay = nextDisplay 

pnlMain.Controls.Add(currentDisplay, 1, 0) 
currentDisplay.Dock = DockStyle.Fill 

currentDisplay.Show() 

End Sub 

Каждый из этих UserControls, которые загружаются есть ListView с большим количеством элементов, которые извлекаются из базы данных. По сути, эти списки заполняются указанными элементами в событии UserControl.Load. Это проблема, потому что UserControl.Paint заметно мерцает/зависает, ожидая заполнения этих больших списков. Моя идея состояла в том, чтобы переместить загрузку списка вне события загрузки UserControl в свой собственный метод и вызвать это после вызова Show(). К сожалению, кажется, что UserControl не закончил Show полностью, прежде чем начать загрузку listview. По крайней мере, он все равно висит точно так же. Почему это так? не заканчивается ли полностью до начала следующей строки? Я подозреваю, что из-за разницы между Show() и ShowDialog(). MSDN говорит, что код продолжает выполняться после вызова Show(), а не ShowDialog(). Как я могу убедиться, что мой UserControl полностью обработан, прежде чем запускать мой метод LoadListView? Я пробовал каждое предложение в Интернете, чтобы свести к минимуму мерцание. Ничего не работает. Мне нужно, чтобы это произошло. Благодаря!

Private Sub treNavTree_NodeMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles treNavTree.NodeMouseClick 

Dim nextDisplay As UserControl = GetUserControl(e.Node.Text) 
If nextDisplay Is Nothing Then Exit Sub 

pnlMain.Controls.Remove(currentDisplay) 
currentDisplay = nextDisplay 

pnlMain.Controls.Add(currentDisplay, 1, 0) 
currentDisplay.Dock = DockStyle.Fill 

currentDisplay.Show() 
currentDisplay.LoadListView() 'Load the listview after done showing 

End Sub 

ответ

0

После попытки несколько различных методов я не удалось найти способ .Show() следующий UserControl без немедленно инициировать загрузку ListView. Теперь я уверен, что он должен запускаться .Show() асинхронно и продолжить обработку следующих строк при загрузке формы, что делает ее неизбежной. Итак, я сделал свой собственный фоновый рабочий и выполнил загрузку списка в этом потоке, загружая UserControl в основной поток, присоединяясь к потоку рабочего фона обратно в основной поток после завершения загрузки.

0

Suspend/ResumeLayout() может сделать трюк:

Private Sub treNavTree_NodeMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles treNavTree.NodeMouseClick 

    Dim nextDisplay As UserControl = GetUserControl(e.Node.Text) 
    If nextDisplay Is Nothing Then Exit Sub 

    Me.SuspendLayout() 
    pnlMain.Controls.Remove(currentDisplay) 
    currentDisplay = nextDisplay 

    currentDisplay.Dock = DockStyle.Fill 
    pnlMain.Controls.Add(currentDisplay, 1, 0) 
    Me.ResumeLayout() 
End Sub 
+0

Спасибо за предложение – Rhurac