CefSharp.v49.0.1浏览器控件完全WPF版,实现禁止弹出新窗口,在同一窗口打开链接,并且支持带type="POST" target="_blank"的链接
需求场景:在查询页面,填写查询条件,查询条件包括上传的图片,根据图片的特征查询,这就需要在提交的时候,使用POST提交,因为GET提交无法提交图片数据,提交查询条件之后,在新的窗口展示查询结果。(当然查询结果页面可能不支持F5刷新页面)
表单HTML代码示意(注意method="post" target="_blank" action指向新页面):
<!DOCTYPE html>
<html>
<head>
<title>提交表单查询</title>
<script type="text/javascript" src='jquery.js'></script>
<script type="text/javascript">
//保存
function save() {
$("#frm").submit();
}
</script>
</head>
<body>
<form id="frm" action="searchResult" enctype="multipart/form-data" method="post" target="_blank">
<input type="text" class="input-text" id="title" name="title" value="测试title" style="width: 300px;" />
<input type="text" class="input-text" id="name" name="name" value="测试name" style="width: 300px;" />
<a href="javascript:void(0);" onclick="save()">保存</a>
</form>
</body>
</html>
请先大致看下Winform版的CefSharp浏览器控件实现方式:
https://www.cnblogs.com/s0611163/p/7716692.html
下面是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
{
/// <summary>
/// 浏览器用户控件
/// </summary>
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; /// <summary>
/// 在此事件中设置URL(此事件已在线程中执行,此事件已对错误情况进行处理)
/// </summary>
public event EventHandler SetUrlEvent; /// <summary>
/// URL
/// </summary>
public string Url { get; set; } /// <summary>
/// 浏览器FrameLoadEnd事件
/// </summary>
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);
} /// <summary>
/// 设置Map控件接口,用于C#和JS互操作
/// </summary>
public void SetMapCtrl(IMapCtrl mapCtrl)
{
_jsObject.MapCtrl = mapCtrl;
} /// <summary>
/// 释放资源
/// </summary>
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(); 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, , , (int)browserContainer.ActualWidth, (int)browserContainer.ActualHeight); browserContainer.SizeChanged += (ss, ee) =>
{
hwndChild = FindWindowEx(control.Handle, IntPtr.Zero, null, null);
MoveWindow(hwndChild, , , (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();
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", "");
settings.CefCommandLineArgs.Add("enable-media-stream", ""); if (!Cef.Initialize(settings, shutdownOnProcessExit: true, performDependencyCheck: true))
{
throw new Exception("Unable to Initialize Cef");
}
}
#endregion }
}
核心代码(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, , , (int)browserContainer.ActualWidth, (int)browserContainer.ActualHeight); browserContainer.SizeChanged += (ss, ee) =>
{
hwndChild = FindWindowEx(control.Handle, IntPtr.Zero, null, null);
MoveWindow(hwndChild, , , (int)browserContainer.ActualWidth, (int)browserContainer.ActualHeight, true);
};
}
catch (Exception ex)
{
_log.Error("BrowserCtrl BindBrowser error", ex);
}
};
核心代码(资源释放):
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
//如果有弹出窗口则先释放它
foreach (UIElement item in grid.Children)
{
if (item is BrowserContainer)
{
(item as BrowserContainer).ClearResource();
}
} if (_browser != null && !_browser.IsDisposed)
{
_browser.Dispose();
}
}
难点:弹出窗口和原来的窗口似乎共用同一个ChromiumWebBrowser实例的某些东西,但是弹出的窗口本身又获取不到ChromiumWebBrowser实例,某些操作不便。
CefSharp.v49.0.1浏览器控件完全WPF版,实现禁止弹出新窗口,在同一窗口打开链接,并且支持带type="POST" target="_blank"的链接的更多相关文章
- CefSharp禁止弹出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接
说明:在同一窗口打开链接,只要稍加改造就可以实现,这里实现的是在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接 gi ...
- CefSharp禁止弹出新窗体,在同一窗口打开链接,并且支持带type="POST" target="_blank"的链接
1.实现ILifeSpanHandler接口,代码如下: using CefSharp; using CefSharp.WinForms; using System; using System.Col ...
- 给Webkit内核的浏览器控件增加互交功能
转载请说明出处,谢谢~~ 昨天封装了基于webkit的wke浏览器内核,做成了duilib的浏览器控件,实现了浏览功能,但是单单的浏览功能还不满足需求,在我的仿酷狗项目中乐库的功能需要与浏览器互交. ...
- java浏览器控件jxbrowser(简单demo模拟自动登录与点击)
写在前面: 老大让我写个脚本自动给他写dms有一段时间了,说实话当时不知道老大指的这个脚本是什么?毕竟是做web的,难道是写个数据库sql语句脚本吗?也就放在了一边.巧了,最近一个朋友说他之前写了个程 ...
- DotnetBrowser入门教程-(1)浏览器控件使用
先简单介绍下DotnetBrowser作为基本浏览器控件的使用: 1.创建基于.net 4.0的桌面项目,如下所示: 2.首次使用的时候在工具栏里添加dotnetbrowser控件,如下图所示: 3. ...
- 用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件
用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件用C#编写ActiveX控件 开发浏览器控件这是本控件开发完成后的一个简单应用.我们可以利用它以本地文件夹为单位来批量更新服务器的 ...
- 与众不同 windows phone (34) - 8.0 新的控件: LongListSelector
[源码下载] 与众不同 windows phone (34) - 8.0 新的控件: LongListSelector 作者:webabcd 介绍与众不同 windows phone 8.0 之 新的 ...
- 基于wke封装的duilib的webkit浏览器控件,可以c++与js互交,源码及demo下载地址
转载请说明原出处,谢谢~~ 前些日子用wke内核封装了duilib的webkit浏览器控件,好多群里朋友私聊我希望可以我公布源码,今天把这个控件的源码和使用demo公布.其实这个控件封装起来没什么难度 ...
- 将webkit内核封装为duilib的浏览器控件
转载请说明出处,谢谢~~ 原本的duilib是自带浏览器控件的,但是使用了IE内核,我在做仿酷狗音乐播放器时,在右侧乐库要用到浏览器控件,而我使用自带的IE控件却发现了不少缺点,这也是duilib一直 ...
随机推荐
- cpp 区块链模拟示例(七) 补充 Merkle树
Merkle 树 完整的比特币数据库(也就是区块链)需要超过 140 Gb 的磁盘空间.因为比特币的去中心化特性,网络中的每个节点必须是独立,自给自足的,也就是每个节点必须存储一个区块链的完整副本.随 ...
- Nodejs学习笔记:基础
本文章主要记录Nodejs基础知识点 安装 首先从Node.js官网下载安装包,并添加到环境变量.然后打开命令行,输入 node --version ,可查看版本信息 npm是Node.js的包管理工 ...
- 使用jackson美化输出json/xml
转载:http://www.cnblogs.com/xiwang/ 如何使用jackson美化输出json/xml 1.美化POJO序列化xml 下面将POJO列化为xml并打印. Person pe ...
- MySQL把本地数据库上传到linux
今天是要导入数据库到linux系统 先用Navicat把sql导出,然后登陆到linux去执行 登陆mysql: mysql -uroot -p123456 创建数据库:create database ...
- 50.IOS上传APP问题
更新版本的时候遇到几个问题 1.ERROR ITMS-90535: "Unexpected CFBundleExecutable Key. The bundle at 'Payload/di ...
- 695. Max Area of Island
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...
- 2018.11.17 hdu5829Rikka with Subset(ntt)
传送门 nttnttntt基础题. 考虑计算每一个数在排名为kkk时被统计了多少次来更新答案. 这样的话,设anskans_kansk表示所有数的值乘上排名为kkk的子集数的总和. 则ansk=∑i ...
- Liferay
Liferay是一个开源公司,我们一般谈Liferay是指的Liferay Portal.Liferay Portal始创于2000年的洛杉机,当时是一个非营利性组织.于2004年建立Liferay公 ...
- poj-1195(二维树状数组)
题目链接:传送门 题意:给出操作,按照操作进行. 思路:将树状数组设置为二维的就行了. 注意: (1)每次求出的面积是S(x2,y2)-S(x1-1,y2)-S(x2,y1-1)+S(x1-1,y1- ...
- 关于oracle的基础增删改查操作总结
① 进入数据库: sqlplus“/as sysdba” 或者sqlplus / as sysdba 注:完整格式: sqlplus“用户名/密码@数据库名as sysdba” 注:请注意,sqlp ...