请选择 进入手机版 | 继续访问电脑版

AYUI WPF技术论坛

搜索
查看: 2707|回复: 0

在WPF中使用CefSharp嵌入浏览器

[复制链接]

18

主题

23

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
10964
QQ
发表于 2016-6-7 22:04:22 | 显示全部楼层 |阅读模式

日常开发中,我们需要将一些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"              designHeight="300" designWidth="300">    <Grid x:Name="MainGrid">        <uc:MaskLoading x:Name="maskLoading"/>    </Grid></UserControl>

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上来承载,

UI:

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

        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页面与客户端程序之间的交互。点击这里下载代码。




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表