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