在WPF中使用CefSharp嵌入瀏覽器

平常開發中,咱們須要將一些Web頁面嵌入到桌面客戶端軟件中。下面咱們使用CefSharp嵌入瀏覽器來實現。 javascript

首先先介紹一下CefSharp嵌入式瀏覽器,它是基於Google瀏覽器的一個組件,咱們能夠在WPF/WinForm客戶端軟件中使用它。CefSharp的代碼託管在GitHub上,.NET (WPF and Windows Forms) bindings for the Chromium Embedded Frameworkhtml

目前最新版本的CefSharp是41.0版本,若是你的客戶端軟件須要支持WIN XP操做系統,建議使用CefSharp.Wpf 1.25.7及以前的版本。能夠從Nuget上獲取到具體的內容。在新版本的CefSharp中,已經取消了對WIN XP系統的支持。java

具體的實現:(首先引用CefSharp.dll,CefSharp.Wpf.dll 另外將icudt.dll,libcef.dll這兩個Dll放置在bin/Debug或者bin/Release目錄下)git

先建立一個UserControl,並繼承IRequestHandler接口,代碼以下:github

UI:express

<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上來承載,this

UI:url

    <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>

Code:spa

        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頁面與客戶端程序之間的交互。點擊這裏下載代碼。

感謝您的閱讀!

相關文章
相關標籤/搜索