在页面聚焦之前先将其加载到CefSharp中

时间:2019-04-14 00:24:55

标签: javascript c# wpf cefsharp

TL; DR-在控件获得焦点之前,是否有任何方法可以将页面加载到CefSharp中?即使我提供了URL,它也只会在控件获得焦点时才开始加载。

完整版本:

我有一个WPF应用程序,该应用程序具有一个带有五个选项卡的Tabcontrol,在其中两个选项卡中,我想加载两个经常在使用该应用程序时使用的网页。这两个站点都加载各自的登录页面,然后我有Javascript命令通过ExecuteJavaScriptAsync()进行登录。

为此,我创建了一个托管ChromiumWebBrowser控件的Usercontrol,它完全正常运行 ,只有当我实际单击每个Web浏览器标签时,页面才会加载-换句话说,似乎只有在获得明确关注时才会发生加载。

我需要的是CefSharp仅在后台加载页面,以便当用户确实需要访问网页选项卡时,网站已经加载并且用户已登录。

以前,我使用的是GeckoBrowser,可根据需要在后台加载页面,但由于该控件存在无法捕获的内部错误,导致我的应用不断崩溃,因此我无法再使用该控件。我也无法使用WebView或更旧的WebControl,因为我无法获取Javascript命令来登录每个站点以正常工作。

我在下面添加了XAML和代码(尽管我并不认为它们确实是必要的),但我的问题确实很简单-如何在控件获得焦点之前将页面加载到CefSharp中?

这是我MainWindow.xaml中的选项卡...

<TabItem>

    <TabItem.Header>
        <TextBlock Text="Rebrickable" Style="{StaticResource HeaderTextBlockStyle}"/>
    </TabItem.Header>

    <Grid Name="grdRebrickable" Background="AliceBlue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
    </Grid>
</TabItem>

<TabItem>
    <TabItem.Header>
        <TextBlock Text="BrickLink" Style="{StaticResource HeaderTextBlockStyle}"/>
    </TabItem.Header>

    <Grid Name="grdBrickLink" Background="AliceBlue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
    </Grid>
</TabItem>

...并且在后面的代码中有这个,当MainWindow启动时会被调用:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
      //Instantiate our browser controls, add them to each of the tab items and load their home pages.
      PrepareBrowserControls();
}

private void PrepareBrowserControls()
{
    csBrickLink = new CefSharpBrowser(BrowserType.BrickLink, AppGlobals.BrickLinkBaseURL);
    grdBrickLink.Children.Add(csBrickLink);
    csBrickLink.LoadURL(AppGlobals.BrickLinkBaseURL);

    csRebrickable = new CefSharpBrowser(BrowserType.Rebrickable, AppGlobals.RebrickableBaseURL);
    grdRebrickable.Children.Add(csRebrickable);
    csRebrickable.LoadURL(AppGlobals.RebrickableBaseURL);
}

用于CefSharpBrowser用户控件的XAML:

<UserControl x:Class="MOCManager.Controls.CefSharpBrowser"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:cef="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
   xmlns:local="clr-namespace:MOCManager.Controls"
   mc:Ignorable="d" >

    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

        <!-- other XAML here left out for brevity -->

        <cef:ChromiumWebBrowser x:Name="cefBrowser"    
             FrameLoadEnd="cefBrowser_FrameLoadEnd" />

    </Grid>
</UserControl>

以及UserControl的核心代码(为简洁起见,省略了一些内容):

    public partial class CefSharpBrowser : UserControl
    {
        //enumeration of site types to load
        private BrowserType _browserType;

        //Login page URL of the sire to load    
        private string _baseURL;

        public CefSharpBrowser(BrowserType browserType, string baseUrl)
        {
            InitializeComponent();

            this._browserType = browserType;
            this._baseURL = baseUrl;
        }

        public void LoadURL(string url)
        {
            if (!string.IsNullOrEmpty(url) && url.ToLower().StartsWith("http"))
                cefBrowser.Address = url;
            else
                MessageBox.Show("Invalid or missing URL!");
        }

       private void cefBrowser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
       {
            if (e.Frame.IsMain)
            {
                Application.Current.Dispatcher.Invoke(new Action(delegate
                {
                    txtURL.Text = e.Url;
                    txtStatus.Text = "Page loaded";
                }));

                //Do automated logins depending on the site 
                if (e.Url.Contains("login/?next="))
                {
                    SetStatus("Logging into Rebrickable...");

                    cefBrowser.GetMainFrame().ExecuteJavaScriptAsync("$('input[name=username]').val(\"joebloggs\")");
                    cefBrowser.GetMainFrame().ExecuteJavaScriptAsync("$('input[name=password]').val(\"abc123\")");
                    cefBrowser.GetMainFrame().ExecuteJavaScriptAsync("$('button[type=\"submit\"]').click();");
                }
                else
                {
                    if (e.Url.Contains("login.page"))
                    {
                        SetStatus("Logging into BrickLink...");

                        cefBrowser.GetMainFrame().ExecuteJavaScriptAsync("$('input[name=frmUsername]').val(\"joebloggs\")");
                        cefBrowser.GetMainFrame().ExecuteJavaScriptAsync("$('input[name=frmPassword]').val(\"abc123\")");
                        cefBrowser.GetMainFrame().ExecuteJavaScriptAsync("$('input[name=frmStayLoggedIn]').checked=true");
                        cefBrowser.GetMainFrame().ExecuteJavaScriptAsync("$('button[type=\"submit\"]').click();");
                    }
                }
            }
        }
   }

0 个答案:

没有答案
相关问题