博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CefSharp.v49.0.1浏览器控件完全WPF版,实现禁止弹出新窗口,在同一窗口打开链接,并且支持带type="POST" target="_blank"的链接...
阅读量:6859 次
发布时间:2019-06-26

本文共 11975 字,大约阅读时间需要 39 分钟。

    需求场景:在查询页面,填写查询条件,查询条件包括上传的图片,根据图片的特征查询,这就需要在提交的时候,使用POST提交,因为GET提交无法提交图片数据,提交查询条件之后,在新的窗口展示查询结果。(当然查询结果页面可能不支持F5刷新页面)

表单HTML代码示意(注意method="post" target="_blank" action指向新页面):

    提交表单查询            
保存
View Code

请先大致看下Winform版的CefSharp浏览器控件实现方式:

下面是WPF版的CefSharp浏览器控件的实现方式,与Winform版相同的代码这里不再粘贴:

using CefSharp;using log4net;using SunCreate.Vipf.Base;using SunCreate.Vipf.Client.Bussiness;using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Runtime.InteropServices;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Interop;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace SunCreate.Vipf.Client.UI{    ///     /// 浏览器用户控件    ///     public partial class BrowserCtrl : UserControl, IDisposable    {        [DllImport("user32.dll", SetLastError = true)]        private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);        [DllImport("user32.dll", SetLastError = true)]        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);        [DllImport("user32.dll", SetLastError = true)]        public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool BRePaint);        [DllImport("user32.dll", SetLastError = true)]        public static extern int CloseWindow(IntPtr hWnd);        [DllImport("User32.dll", EntryPoint = "GetWindowText")]        private static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);        private ILog _log = LogManager.GetLogger(typeof(BrowserCtrl));        private static bool _isCefInited = false;        private static object _lockObject = new object();        private JSObject _jsObject;        private bool _firstLoad = true;        ///         /// 在此事件中设置URL(此事件已在线程中执行,此事件已对错误情况进行处理)        ///         public event EventHandler SetUrlEvent;        ///         /// URL        ///         public string Url { get; set; }        ///         /// 浏览器FrameLoadEnd事件        ///         public event EventHandler FrameLoadEnd;        private ExtChromiumBrowser _browser;        public ExtChromiumBrowser Browser        {            get            {                return this._browser;            }        }        public BrowserCtrl()        {            InitializeComponent();            if (DesignerProperties.GetIsInDesignMode(this)) return;            this.Loaded += BrowserCtrl_Loaded;            lock (_lockObject)            {                if (!_isCefInited)                {                    _isCefInited = true;                    InitCef(true);//初始化CefSharp                }            }            _browser = new ExtChromiumBrowser();            BindBrowser(_browser);            grid.Children.Add(_browser);        }        ///         /// 设置Map控件接口,用于C#和JS互操作        ///         public void SetMapCtrl(IMapCtrl mapCtrl)        {            _jsObject.MapCtrl = mapCtrl;        }        ///         /// 释放资源        ///         public void Dispose()        {            //如果有弹出窗口则先释放它            foreach (UIElement item in grid.Children)            {                if (item is BrowserContainer)                {                    (item as BrowserContainer).ClearResource();                }            }            if (_browser != null && !_browser.IsDisposed)            {                _browser.Dispose();            }        }        private void BrowserCtrl_Loaded(object sender, RoutedEventArgs e)        {        }        private void LoadUrl()        {            if (_firstLoad)            {                _firstLoad = false;                System.Threading.Tasks.Task.Factory.StartNew(() =>                {                    Thread.Sleep(100);                    if (Url == null && SetUrlEvent != null)                    {                        try                        {                            SetUrlEvent(this, null);                        }                        catch (Exception ex)                        {                            _log.Error("BrowserCtrl LoadUrl error 获取URL失败", ex);                        }                    }                    this.Dispatcher.Invoke(new Action(() =>                    {                        _browser.Load(Url);                    }));                });            }        }        private void BindBrowser(ExtChromiumBrowser browser)        {            _jsObject = new JSObject();            browser.RegisterJsObject("jsObj", _jsObject, false);            browser.StartNewWindow += (s, e) =>            {                try                {                    IntPtr hwndChild = IntPtr.Zero; //浏览器弹出窗口句柄                    BrowserContainer browserContainer = new BrowserContainer();                    System.Windows.Forms.Control control = new System.Windows.Forms.Control();                    control.Dock = System.Windows.Forms.DockStyle.Fill;                    control.CreateControl();                    browserContainer.host.Child = control;                    browserContainer.ClearResourceEvent += (ss, ee) =>                    {                        CloseWindow(hwndChild);                        control.Dispose();                        browserContainer.host.Dispose();                    };                    //释放上一个弹出窗口                    foreach (UIElement item in grid.Children)                    {                        if (item is BrowserContainer)                        {                            (item as BrowserContainer).ClearResource();                        }                    }                    grid.Children.Clear();                    grid.Children.Add(browserContainer);                    e.WindowInfo.SetAsChild(control.Handle, 0, 0, (int)browserContainer.ActualWidth, (int)browserContainer.ActualHeight);                    browserContainer.SizeChanged += (ss, ee) =>                    {                        hwndChild = FindWindowEx(control.Handle, IntPtr.Zero, null, null);                        MoveWindow(hwndChild, 0, 0, (int)browserContainer.ActualWidth, (int)browserContainer.ActualHeight, true);                    };                }                catch (Exception ex)                {                    _log.Error("BrowserCtrl BindBrowser error", ex);                }            };            browser.IsBrowserInitializedChanged += (ss, ee) =>            {                LoadUrl();            };            browser.FrameLoadStart += (ss, ee) =>            {                this.Dispatcher.BeginInvoke(new Action(() =>                {                    (ss as ExtChromiumBrowser).Focus();                }));            };            browser.FrameLoadEnd += (ss, ee) =>            {                this.Dispatcher.BeginInvoke(new Action(() =>                {                    loadingWait.Visibility = Visibility.Collapsed;                }));                if (FrameLoadEnd != null)                {                    FrameLoadEnd(null, null);                }            };            browser.KeyDown += (ss, ee) =>            {                if (ee.Key == Key.D)                {                    //_browser.ExecuteScriptAsync("dayOrNightMap", 0);                }                if (ee.Key == Key.N)                {                    //_browser.ExecuteScriptAsync("dayOrNightMap", 1);                }            };            browser.LoadError += (ss, ee) =>            {                _log.Error("ExtChromiumBrowser LoadError 错误码:" + ee.ErrorCode + ",错误信息:" + ee.ErrorText + ",错误URL:" + ee.FailedUrl);                return; //下面代码不执行                System.Threading.Tasks.Task.Factory.StartNew(() =>                {                    if (Url == null && SetUrlEvent != null)                    {                        try                        {                            SetUrlEvent(this, null);                        }                        catch (Exception ex)                        {                            _log.Error("BrowserCtrl LoadUrl error 获取URL失败", ex);                        }                    }                    Thread.Sleep(500);                    this.Dispatcher.BeginInvoke(new Action(() =>                    {                        (ss as ExtChromiumBrowser).Load(Url);                    }));                });            };        }        #region 初始化CefSharp        public static void InitCef(bool multiThreadedMessageLoop)        {            string cefsharpFolder = "CefSharp.v49.0.1";            var settings = new CefSettings();            //The location where cache data will be stored on disk. If empty an in-memory cache will be used for some features and a temporary disk cache for others.            //HTML5 databases such as localStorage will only persist across sessions if a cache path is specified.             // settings.CachePath = cefsharpFolder + "/cache"; //注释掉,不使用cache            settings.MultiThreadedMessageLoop = multiThreadedMessageLoop;            settings.FocusedNodeChangedEnabled = true;            Cef.OnContextInitialized = delegate            {                var cookieManager = Cef.GetGlobalCookieManager();                cookieManager.SetStoragePath(cefsharpFolder + "/cookies", true);                cookieManager.SetSupportedSchemes("custom");            };            settings.BrowserSubprocessPath = AppDomain.CurrentDomain.BaseDirectory + cefsharpFolder + "/CefSharp.BrowserSubprocess.exe";            settings.LogFile = cefsharpFolder + "/debug.log";            settings.CefCommandLineArgs.Add("disable-gpu", "1");            settings.CefCommandLineArgs.Add("enable-media-stream", "1");            if (!Cef.Initialize(settings, shutdownOnProcessExit: true, performDependencyCheck: true))            {                throw new Exception("Unable to Initialize Cef");            }        }        #endregion    }}
View Code

 核心代码(StartNewWindow):

browser.StartNewWindow += (s, e) =>{    try    {        IntPtr hwndChild = IntPtr.Zero; //浏览器弹出窗口句柄        BrowserContainer browserContainer = new BrowserContainer();        System.Windows.Forms.Control control = new System.Windows.Forms.Control();        control.Dock = System.Windows.Forms.DockStyle.Fill;        control.CreateControl();        browserContainer.host.Child = control;        browserContainer.ClearResourceEvent += (ss, ee) =>        {            CloseWindow(hwndChild);            control.Dispose();            browserContainer.host.Dispose();        };        //释放上一个弹出窗口        foreach (UIElement item in grid.Children)        {            if (item is BrowserContainer)            {                (item as BrowserContainer).ClearResource();            }        }        grid.Children.Clear();        grid.Children.Add(browserContainer);        e.WindowInfo.SetAsChild(control.Handle, 0, 0, (int)browserContainer.ActualWidth, (int)browserContainer.ActualHeight);        browserContainer.SizeChanged += (ss, ee) =>        {            hwndChild = FindWindowEx(control.Handle, IntPtr.Zero, null, null);            MoveWindow(hwndChild, 0, 0, (int)browserContainer.ActualWidth, (int)browserContainer.ActualHeight, true);        };    }    catch (Exception ex)    {        _log.Error("BrowserCtrl BindBrowser error", ex);    }};
View Code

核心代码(资源释放):

/// /// 释放资源/// public void Dispose(){    //如果有弹出窗口则先释放它    foreach (UIElement item in grid.Children)    {        if (item is BrowserContainer)        {            (item as BrowserContainer).ClearResource();        }    }    if (_browser != null && !_browser.IsDisposed)    {        _browser.Dispose();    }}
View Code

 难点:弹出窗口和原来的窗口似乎共用同一个ChromiumWebBrowser实例的某些东西,但是弹出的窗口本身又获取不到ChromiumWebBrowser实例,某些操作不便。

 

转载于:https://www.cnblogs.com/s0611163/p/10115501.html

你可能感兴趣的文章
View的setTag()与getTag()方法使用
查看>>
2009年云数据库的开发和应用前景(转载)
查看>>
咏南中间件更新日志
查看>>
在rem布局下使用背景图片以及sprite
查看>>
JAVA设计模式之【抽象工厂模式】
查看>>
数字电视的电子节目指南(EPG)及其系统
查看>>
11 复用与多址
查看>>
附录A 编译安装Hadoop
查看>>
android studio building project info 错误
查看>>
【Scala】Scala之Control Structures
查看>>
三星手机拍照,从图库选择照片旋转问题完美解决
查看>>
算法笔记_173:历届试题 斐波那契(Java)
查看>>
菜鸟版JAVA设计模式—外观模式
查看>>
EasyUI----动态拼接EasyUI控件
查看>>
PHP session 跨子域问题总结 ini_set('session.cookie_domain', ".domain.com")
查看>>
Office WPS如何在页眉页脚添加一条横线
查看>>
站在 Android 开发的角度,聊聊 Airbnb 的 Lottie!!!
查看>>
数组去重Demo引出的思考
查看>>
javascript怎么禁用浏览器后退按钮
查看>>
AtomicLong可以被原子地读取和写入的底层long值的操作
查看>>