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

时间:2016-12-10 01:24:47

标签: vb.net winforms user-controls

我有一个主窗口形式,就像一个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在等待填充这些大型列表视图时明显闪烁/挂起。我的想法是将listview加载到UserControl的Load事件之外,移动到它自己的方法中,并在调用Show()之后调用它。不幸的是,似乎UserControl在开始加载listview之前没有完全完成Show。至少,它仍然以完全相同的方式挂起。为什么会这样?是不是在开始下一行之前完成了?我怀疑是这样,因为Show()和ShowDialog()之间存在差异。 MSDN表示,在调用Show()而不是ShowDialog()之后,代码将继续执行。在运行LoadListView方法之前,如何确保我的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()
currentDisplay.LoadListView()  'Load the listview after done showing

End Sub

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

在尝试了几种不同的方法之后,我无法在没有立即启动ListView加载的情况下找到.Show()下一个UserControl的方法。我现在很确定它必须异步运行.Show()并在加载表单时继续处理下一行,这使得它不可避免。所以,我创建了自己的后台工作者并在该主题上加载了listview,同时在主线程上加载UserControl,在加载完成后将后台工作线程连接回主线程。