日常開發中,我們需要将一些Web頁面嵌入到桌面用戶端軟體中。下面我們使用CefSharp嵌入浏覽器來實作。
首先先介紹一下CefSharp嵌入式浏覽器,它是基于Google浏覽器的一個元件,我們可以在WPF/WinForm用戶端軟體中使用它。CefSharp的代碼托管在GitHub上,
.NET (WPF and Windows Forms) bindings for the Chromium Embedded Framework。
目前最新版本的CefSharp是41.0版本,如果你的用戶端軟體需要支援WIN XP作業系統,建議使用CefSharp.Wpf 1.25.7及之前的版本。可以從
Nuget上擷取到具體的内容。在新版本的CefSharp中,已經取消了對WIN XP系統的支援。
具體的實作:(首先引用CefSharp.dll,CefSharp.Wpf.dll 另外将icudt.dll,libcef.dll這兩個Dll放置在bin/Debug或者bin/Release目錄下)
先建立一個UserControl,并繼承IRequestHandler接口,代碼如下:
UI:
<UserControl x:Class="EmbeddedWebBrowserSolution.WebPageViewer"
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:local="clr-namespace:EmbeddedWebBrowserSolution"
xmlns:uc="clr-namespace:EmbeddedWebBrowserSolution"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="MainGrid">
<uc:MaskLoading x:Name="maskLoading"/>
</Grid>
</UserControl>
Code:
public partial class WebPageViewer : UserControl, IRequestHandler
{
private WebView _view;
public WebPageViewer(string url)
{
InitializeComponent();
CEF.Initialize(new Settings { LogSeverity = LogSeverity.Disable, PackLoadingDisabled = true });
BrowserSettings browserSetting = new BrowserSettings { ApplicationCacheDisabled = true, PageCacheDisabled = true };
_view = new WebView(string.Empty, browserSetting)
{
Address = url,
RequestHandler = this,
Background = Brushes.White
};
_view.LoadCompleted += _view_LoadCompleted;
MainGrid.Children.Insert(0, _view);
}
private void _view_LoadCompleted(object sender, LoadCompletedEventArgs url)
{
Dispatcher.BeginInvoke(new Action(() =>
{
maskLoading.Visibility = Visibility.Collapsed;
}));
}
public void View(string url)
{
if(_view.IsBrowserInitialized)
{
_view.Visibility = Visibility.Hidden;
maskLoading.Visibility = Visibility.Visible;
_view.Load(url);
}
}
#region IRequestHandler
public bool GetAuthCredentials(IWebBrowser browser, bool isProxy, string host, int port, string realm, string scheme, ref string username, ref string password)
{
return false;
}
public bool GetDownloadHandler(IWebBrowser browser, string mimeType, string fileName, long contentLength, ref IDownloadHandler handler)
{
return true;
}
public bool OnBeforeBrowse(IWebBrowser browser, IRequest request, NavigationType naigationvType, bool isRedirect)
{
return false;
}
public bool OnBeforeResourceLoad(IWebBrowser browser, IRequestResponse requestResponse)
{
return false;
}
public void OnResourceResponse(IWebBrowser browser, string url, int status, string statusText, string mimeType, WebHeaderCollection headers)
{
}
#endregion
}
下一步,在MainWindow上來承載,
<Grid>
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock Text="Address:" Margin="5"/>
<TextBox x:Name="txtAddress" Width="350" Margin="5"/>
<Button Content="Go" Margin="5" Click="OnGoClick" IsDefault="True"/>
</StackPanel>
<Grid x:Name="MainGrid">
</Grid>
</DockPanel>
</Grid>
private void OnGoClick(object sender, RoutedEventArgs e)
{
string url = txtAddress.Text;
if (!string.IsNullOrWhiteSpace(url))
{
WebPageViewer viewer = new WebPageViewer(url);
MainGrid.Children.Insert(0,viewer);
}
}
注意,需要将工程Platform Target設定為X86。
運作效果:

到這裡,一個使用CefSharp來承載Web頁面的例子就算完成了。
相比于WPF内置的WebBrowser,CefSharp在處理JS回掉時,比WebBrowser友善很多。請看下面的例子:
我們有這樣一個HTML頁面:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script type="text/javascript">
function callback()
{
callbackObj.showMessage('message from js');
}
</script>
</head>
<body>
<input type="button" value="Click" onclick="callback()" ID="Button">
</body>
</html>
增加一個類,叫做:CallbackObjectForJs
public class CallbackObjectForJs
{
public void showMessage(string msg)
{
MessageBox.Show(msg);
}
}
注意這個方法的名稱必須小寫。
改造一下WebPageViewer類,在構造後WebView之後,注冊一個JS對象,
//...
public WebPageViewer(string url)
{
InitializeComponent();
CEF.Initialize(new Settings { LogSeverity = LogSeverity.Disable, PackLoadingDisabled = true });
BrowserSettings browserSetting = new BrowserSettings { ApplicationCacheDisabled = true, PageCacheDisabled = true };
_view = new WebView(string.Empty, browserSetting)
{
Address = url,
RequestHandler = this,
Background = Brushes.White
};
_view.RegisterJsObject("callbackObj", new CallbackObjectForJs());
_view.LoadCompleted += _view_LoadCompleted;
MainGrid.Children.Insert(0, _view);
}
//...
運作效果如下:
通過這樣的方式,我們可以很好的實作Web頁面與用戶端程式之間的互動。點選
這裡下載下傳代碼。
感謝您的閱讀!