在WPF中使用CefSharp嵌入浏览器

简介: 原文:在WPF中使用CefSharp嵌入浏览器日常开发中,我们需要将一些Web页面嵌入到桌面客户端软件中。下面我们使用CefSharp嵌入浏览器来实现。  首先先介绍一下CefSharp嵌入式浏览器,它是基于Google浏览器的一个组件,我们可以在WPF/WinForm客户端软件中使用它。
原文: 在WPF中使用CefSharp嵌入浏览器

日常开发中,我们需要将一些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上来承载,

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

感谢您的阅读!

目录
相关文章
|
3月前
|
C#
C# WPF 将第三方DLL嵌入 exe
C# WPF 将第三方DLL嵌入 exe
77 0
|
JavaScript 前端开发 Java
【JCEF】SWT嵌入浏览器(包含VUE的)
【JCEF】SWT嵌入浏览器(包含VUE的)
248 1
WinForm使用CefSharp,嵌入浏览器
WinForm使用CefSharp,嵌入浏览器
549 0
|
移动开发 Linux HTML5
Linux下将swf文件用浏览器读取打开(html、html5嵌入swf格式文件)
Linux下将swf文件用浏览器读取打开(html、html5嵌入swf格式文件)
|
Web App开发 监控 前端开发
C# WPF 嵌入网页版WebGL油田三维可视化监控
C# WPF 嵌入网页版WebGL油田三维可视化监控
C# WPF 嵌入网页版WebGL油田三维可视化监控
|
C#
WPF 嵌入Winform GDI 、 开启AllowsTransparenc问题
原文:WPF 嵌入Winform GDI 、 开启AllowsTransparenc问题 此文章可以解决2至少2个问题: 1.开启AllowsTransparenc造成的GDI+组件不显示问题 2.WPF 组件无法覆盖嵌入WPF窗口的任何第三方GDI+组件上层   方案1:自制双层 原理:用一个新的窗口来承载GDI+组件,实现 父窗口 拖动、缩放、最小化、最大化 的联动 事件。
1247 0
|
Web App开发 C# Android开发
WPF 使用 Edge 浏览器
原文:WPF 使用 Edge 浏览器 本文告诉大家如何使用 Windows Community Toolkit 的新控件,在 WPF 使用 Edge 浏览器 首先需要通过 VisualStudio 创建 WPF 项目。
1356 0
|
C# 数据可视化 容器
WPF自适应可关闭的TabControl 类似浏览器的标签页
原文:WPF自适应可关闭的TabControl 类似浏览器的标签页 效果如图:   虽然说是自适应可关闭的TabControl,但TabControl并不需要改动,不如叫自适应可关闭的TabItem.
2114 0
|
6月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
382 0
|
3月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件