确保 UserControl 在 运行 方法之前完全完成自身绘制

Ensure that UserControl is completely done painting itself before running a method

我有一个像 mdi 窗体一样工作的主窗口窗体。当用户从菜单中选择一个选项时,主窗口将加载一个 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

加载的每个 UserControl 都有一个 ListView,其中包含许多从数据库中获取的项目。就目前而言,这些列表视图填充了 UserControl.Load 事件中的所述项目。这是一个问题,因为在等待这些大型列表视图填充时 UserControl.Paint 明显 flickers/hangs。我的想法是将 Listview 的加载从 UserControl 的 Load 事件移到它自己的方法中,并在调用 Show() 之后调用它。不幸的是,似乎 UserControl 在开始加载列表视图之前并没有完全完成显示。至少,它仍然以完全相同的方式挂起。为什么会这样?在开始下一行之前它没有完全完成吗?我怀疑是这样,因为 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

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

在尝试了几种不同的方法后,我无法找到一种方法来 .Show() 下一个 UserControl,而不立即启动 ListView 的加载。我现在很确定它必须 运行 .Show() 异步并在加载表单时继续处理下一行,这是不可避免的。因此,我创建了自己的后台工作程序并在该线程上加载了列表视图,同时在主线程上加载了 UserControl,加载完成后将后台工作线程连接回主线程。