Содержимое вкладки WinForm TabControl не обновляется до тех пор, пока не будет показана новая вкладка

У меня есть tabcontrol, который позволяет создавать новые вкладки. На каждой новой вкладке есть элемент управления веб-браузером 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 Browser Control плюс некоторый дополнительный пользовательский интерфейс.

А вот код запуска для самого браузера.

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, на котором находится элемент управления, НЕ отображается пользователю.


person Dave Gordon    schedule 20.01.2016    source источник


Ответы (2)


Событие Load произойдет только тогда, когда элемент управления станет видимым в первый раз:

Происходит перед тем, как элемент управления становится видимым в первый раз.

поэтому попробуйте переместить свой метод Execute в код конструктора UserControl.

person LarsTech    schedule 20.01.2016
comment
Лол - даже не подумал об этом! Вы получаете баллы за более простой ответ для реализации. - person Dave Gordon; 21.01.2016

Нет никакого "официального" способа сделать это.

Но если вам это действительно нужно и вы не боитесь использовать внутренности, вы можете взглянуть на мой ответ на WinForms: реагировать на применение BindingSource.

Решение (или хак) заключено в этом маленьком помощнике

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();

or

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();
}
person Ivan Stoev    schedule 20.01.2016