需求场景:在查询页面,填写查询条件,查询条件包括上传的图片,根据图片的特征查询,这就需要在提交的时候,使用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"的链接的更多相关文章

  1. CefSharp禁止弹出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接

    说明:在同一窗口打开链接,只要稍加改造就可以实现,这里实现的是在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接 gi ...

  2. CefSharp禁止弹出新窗体,在同一窗口打开链接,并且支持带type="POST" target="_blank"的链接

    1.实现ILifeSpanHandler接口,代码如下: using CefSharp; using CefSharp.WinForms; using System; using System.Col ...

  3. 给Webkit内核的浏览器控件增加互交功能

    转载请说明出处,谢谢~~ 昨天封装了基于webkit的wke浏览器内核,做成了duilib的浏览器控件,实现了浏览功能,但是单单的浏览功能还不满足需求,在我的仿酷狗项目中乐库的功能需要与浏览器互交. ...

  4. java浏览器控件jxbrowser(简单demo模拟自动登录与点击)

    写在前面: 老大让我写个脚本自动给他写dms有一段时间了,说实话当时不知道老大指的这个脚本是什么?毕竟是做web的,难道是写个数据库sql语句脚本吗?也就放在了一边.巧了,最近一个朋友说他之前写了个程 ...

  5. DotnetBrowser入门教程-(1)浏览器控件使用

    先简单介绍下DotnetBrowser作为基本浏览器控件的使用: 1.创建基于.net 4.0的桌面项目,如下所示: 2.首次使用的时候在工具栏里添加dotnetbrowser控件,如下图所示: 3. ...

  6. 用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件

    用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件用C#编写ActiveX控件 开发浏览器控件这是本控件开发完成后的一个简单应用.我们可以利用它以本地文件夹为单位来批量更新服务器的 ...

  7. 与众不同 windows phone (34) - 8.0 新的控件: LongListSelector

    [源码下载] 与众不同 windows phone (34) - 8.0 新的控件: LongListSelector 作者:webabcd 介绍与众不同 windows phone 8.0 之 新的 ...

  8. 基于wke封装的duilib的webkit浏览器控件,可以c++与js互交,源码及demo下载地址

    转载请说明原出处,谢谢~~ 前些日子用wke内核封装了duilib的webkit浏览器控件,好多群里朋友私聊我希望可以我公布源码,今天把这个控件的源码和使用demo公布.其实这个控件封装起来没什么难度 ...

  9. 将webkit内核封装为duilib的浏览器控件

    转载请说明出处,谢谢~~ 原本的duilib是自带浏览器控件的,但是使用了IE内核,我在做仿酷狗音乐播放器时,在右侧乐库要用到浏览器控件,而我使用自带的IE控件却发现了不少缺点,这也是duilib一直 ...

随机推荐

  1. cxf 介绍

    CXF 编辑     目录 1Apache CXF 简介 关于Apache CXF 功能特性 项目目标 2Apache CXF特点 灵活部署 支持多种编程语言 代码生成     1Apache CXF ...

  2. Twitter 相关APP开发

    首先要获取 Consumer Key (API Key), Consumer Secret (API Secret):最好申请Access Token 和Access Token Secret,不然验 ...

  3. python学习 day18 (3月25日)---( 面向对象浅析)

    面向对象思想: 字典表示对象: 不是太好 因为 变量 得一个个的赋值改值 {'name':'alex','blood':20,'attack':1,'sex':'不'} {'name':'太亮','b ...

  4. idea如何搭建springboot框架

    首先简单介绍下Spring Boot,来自度娘百科:Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进 ...

  5. 2018.11.24 poj3693Maximum repetition substring(后缀数组)

    传送门 后缀数组好题. 考虑枚举循环节长度lenlenlen. 然后考虑枚举循环节的起点来更新答案. 但是直接枚举每次O(n)O(n)O(n). 考虑枚举len∗k+1len*k+1len∗k+1作为 ...

  6. poj-3667(线段树区间合并)

    题目链接:传送门 参考文章:传送门 思路:线段树区间合并问题,每次查询到满足线段树的区间最左值,然后更新线段树. #include<iostream> #include<cstdio ...

  7. linux复制文件并修改文件名

    #!/bin/bash #复制/casnw/backup/db203oradata/目录下的所有后缀名为dmp的文件拷贝到/casnw/backup/dbmonthbak 目录下cp -f /casn ...

  8. 委托构造函数(c++11)

    1.概念 1)委托构造函数也是构造函数,它也有形参列表,它将实参传递给其他的构造函数来初始化类对象,像是把自己的一些(或者全部)构造职责委托给其他构造函数一样

  9. Redis源码笔记-初步

    目录 目录 1 1. 前言 2 2. 名词 2 3. dict.c 2 3.1. siphash算法 2 3.2. 核心函数 3 3.3. 核心宏 3 3.4. 核心结构体 3 3.4.1. dict ...

  10. Grand Central Dispatch

    什么是GCD? Grand Central Dispatch或者GCD,是一套低层API,提供了一种新的方法来进行并发程序编写.从基本功能上讲,GCD有点像NSOperationQueue,他们都允许 ...