在动态添加到Controls集合时,防止winforms控件变为可见

时间:2013-11-28 10:29:01

标签: c# winforms mdi mdichild

我创建了一个Form,上面加载Panel。这个想法是我想要显示这个加载面板,直到我的动态创建的控件准备好显示。

最初可以看到加载Panel,然后在OnShown事件期间创建我的控件并将其添加到页面中。我使用OnShown的原因是Form正在Mdi场景中使用,所以我需要在开始加载控件之前完全显示它(如果我在Load事件中尝试这个,那么在我的控件加载之前,Mdi Tab不显示。

问题在于有明显的闪烁,我认为这是因为当我将控件添加到Controls集合时:

a)Visible属性立即设置为true。 b)即使z-index看起来是正确的,我的控制似乎也出现在加载面板的前面。

这是问题的核心

    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,这样我可以在控件的Load事件完成时设置Visible = true。相反,我的控制进入视野,我得到闪烁。有趣的是,如果我在任何时候都没有设置loadingPanel.Visible = false,那么一旦我的控件加载完毕,loadPanel会重新出现并隐藏我的控制权。

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

我认为你的mycontrol是一个标准的winforms控件?为什么不在其中创建包含所需mycontrol的自定义控件,并且在该自定义控件中,默认为" child"控制可见属性为假?

没有测试过这个,但那就是接下来会做什么......?

答案 1 :(得分:0)

您无需更改Visible,即使您将其设置为false成功,当您向后显示时,如果控件数量很大,仍然会有一些闪烁。您应该覆盖OnLoad方法,并使用SuspendLayoutResumeLayout,如下所示:

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

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

我怀疑在完成添加控件后立即使用ResumeLayout(true)可能没问题,你也应该试试。

答案 2 :(得分: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集合添加控件时,如果未创建句柄,则会自动将其设置为Visible。通过在将其添加到集合之前使其可见,创建相关句柄不会影响父控件。然后,当它稍后添加到集合中时,它仍然不会干扰父控件。