在显示新选项卡之前,WinForm TabControl选项卡页面内容不会更新

时间:2016-01-20 18:11:48

标签: c# winforms tabs user-controls cefsharp

我有一个tabcontrol,允许创建新标签。每个新选项卡上都有一个Web浏览器控件CEFSharp。创建新选项卡时,未显示先前打开的选项卡;这就是我们想要的。

但是,新创建的选项卡上的浏览器仅添加到选项卡页面,并且仅部分运行...在显示选项卡页面之前,它不会进入加载状态。

以下是Tabpage创建代码:

private void AddNewBrowser()
        {
            Log("Adding New Tab and Browser");

            UiBrowser browser = new UiBrowser();

            TabPage tp = new TabPage();

            tp.Controls.Add(browser);
            customTabControl1.TabPages.Add(tp);
        }

UiBrowser是一个UserControl,其中包含CEFSharp浏览器控件和一些额外的UI。

这是浏览器本身的启动代码。

private void UiBrowser_Load(object sender, EventArgs e)
        {
            Execute();
        }

private void Execute()
        {
            webBrowser = new ChromiumWebBrowser("http://google.co.uk")
            {
                Dock = DockStyle.Fill,
                Text = "Loading...",
                Tag = Tag
            };

            webBrowser.TitleChanged += Browser_TitleChanged;
            webBrowser.AddressChanged += Browser_AddressChanged;
            webBrowser.ConsoleMessage += Browser_ConsoleMessage;
            webBrowser.LoadingStateChanged += Browser_LoadingStateChanged;
            webBrowser.StatusMessage += Browser_StatusMessage;

            browserPanel.Controls.Add(webBrowser);
            Application.DoEvents();
        }

为了清晰起见,代码已经过简化,我没有在SO或其他地方找到解决此问题的解决方案。

问题: 如何在浏览器控件加载网页的同时保留在后台?也就是说,控件所在的TabPage不会显示给用户。

2 个答案:

答案 0 :(得分:2)

Load event仅在控件第一次可见时才会发生:

  

在控件第一次可见之前发生。

所以尝试将Execute方法移动到UserControl的构造函数代码中。

答案 1 :(得分:0)

没有“官方”的方式。

但是如果你真的需要它并且不害怕使用内部,你可以看看我对WinForms: Respond to BindingSource being applied的回答。

解决方案(或hack)封装在这个小助手

public static class ControlUtils
{
    static readonly Action<Control, bool> CreateControlFunc = (Action<Control, bool>)Delegate.CreateDelegate(typeof(Action<Control, bool>),
        typeof(Control).GetMethod("CreateControl", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(bool) }, null));

    public static void CreateControls(this Control target)
    {
        if (!target.Created)
            CreateControlFunc(target, true);
        else
            for (int i = 0; i < target.Controls.Count; i++)
                target.Controls[i].CreateControls();
    }
}

在表单加载事件结束时,添加以下

this.CreateControls();

customTabControl1.CreateControls();

也在这里

private void AddNewBrowser()
{
    Log("Adding New Tab and Browser");

    UiBrowser browser = new UiBrowser();

    TabPage tp = new TabPage();

    tp.Controls.Add(browser);
    customTabControl1.TabPages.Add(tp);

    if (customTabControl1.Created)
        tp.CreateControls();
}