基于CefSharp开发(二)自定义浏览器窗体
上一篇 https://www.cnblogs.com/mchao/p/13914726.html 简单了解了CefSharp引用配置但页面光秃秃的,这一篇着手开发简单浏览器窗体
一、Edge浏览器窗体分析

如上图所示可先将浏览器窗体分为两大部分,Header及Body部分,Header暂时分为Tab展示及搜索部分 每个Tab页有一个搜索及ChromiumWebBrowser
此时我们需要一个带关闭按钮的TabControl
二、自定义TabControl
修改TabItem ControlTemplate增加Button,关于TabControl分析请参考 Cys_Control(四) MTabControl
<Button Grid.Column="1" Style="{StaticResource TabCloseButton}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MTabControl}},Path=TabItemRemoveCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}" />
CommandParamenter 参数传当前 TabItem
在cs文件中添加依赖属性TabItemRemoveCommand
public static readonly DependencyProperty TabItemRemoveCommandProperty = DependencyProperty.Register("TabItemRemoveCommand", typeof(ICommand), typeof(MTabControl), new PropertyMetadata(null));
public ICommand TabItemRemoveCommand
{
get => (ICommand)GetValue(TabItemRemoveCommandProperty);
set => SetValue(TabItemRemoveCommandProperty, value);
}
并为TabItemRemoveCommand添加移除方法
private void TabItemRemove(object obj)
{
if (obj is TabItem item)
{
this.Items.Remove(item);
}
}
有了移除还需要有新增

在 TabControl中添加 Button,原理同移除
<Button Grid.Column="1" Style="{StaticResource TabAddButton}" HorizontalAlignment="Left"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MTabControl}},Path=TabItemAddCommand}"/>

三、添加搜索框

由图可知 Edge 搜索框由 三部分组成即(左右按钮及中间文本),相当于TextBox中增加了俩按钮,因此我们对TextBox做个扩展
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button Style="{DynamicResource Button.NavigationSearch}" Margin="2,0"/>
</Grid>
<Grid Grid.Column="1">
<ScrollViewer x:Name="PART_ContentHost" FontSize="{TemplateBinding FontSize}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" BorderThickness="0" IsTabStop="False"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,0"/>
<!--水印-->
<TextBlock x:Name="Part_Watermark" Text="{TemplateBinding Watermark}" FontSize="{TemplateBinding FontSize}" Visibility="Hidden" HorizontalAlignment="Left"
Foreground="{DynamicResource ColorBrush.FontWatermarkColor}" IsHitTestVisible="False" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="5,0"/>
</Grid>
<Grid Grid.Column="2">
<ToggleButton Style="{DynamicResource ToggleButton.NavigationCollection}" Margin="2,0"/>
</Grid>
</Grid>
文本框中左边增加Button,右边增加ToggleButton来区分是否网页已收藏(注:本次不加入业务处理)
关于TextBox水印及其他处理 请参照 Cys_Control(三) MTextBox

四、调整布局
增加前进回退刷新等按钮用于占位并调整搜索框
<Grid Grid.Row="0" Background="{DynamicResource WebBrowserBrushes.TabHeaderIsSelectedBackground}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<Button Style="{DynamicResource Button.NavigationBack}"/>
<Button Style="{DynamicResource Button.NavigationForward}"/>
<Button Style="{DynamicResource Button.NavigationRefresh}"/>
</StackPanel>
<controls:MTextBox Grid.Column="1" Watermark="搜索或输入Web地址" x:Name="SearchText"/>
<Grid Grid.Column="2" MinWidth="150">
</Grid>
</Grid>

此时从页面上看已经有些像浏览器了,跑起来。。。

此时发现点击网页链接和预想的打开新Tab页有些差距
五、新Tab页打开链接
Cef的Popup处理定义在ILifeSpanHandler接口中,若要阻止弹窗并使用自己的Tab页则应该自定义LifeSpanHandler
新增CustomLifeSpanHandler类并实现ILifeSpanHandler接口
public class CustomLifeSpanHandler : ILifeSpanHandler
{
public bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl,
string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures,
IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
{
if (chromiumWebBrowser is CustomWebBrowser webBrowser)
{
webBrowser.OpenNewTab(targetUrl);
}
newBrowser = null;
return true;
} public void OnAfterCreated(IWebBrowser chromiumWebBrowser, IBrowser browser)
{ } public bool DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
return false;
} public void OnBeforeClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
{ }
}
OnBeforePopup方法中可以取到 targetUrl也就是点击的<a>标签中的链接
此时我们需要将targetUrl传递到WebBrowser中,由于我们需要打开Tab页,需要增加一个方法 OpenNewTab(targetUrl),
ChromiumWebBrowser类并不能满足我们的使用场景,故扩展ChromiumWebBrowser类,新增CustomWebBrowser继承于ChromiumWebBrowser
并添加 OpenNewTab方法
public void OpenNewTab(string url)
{
Dispatcher.Invoke(() =>
{
var tabControl = ControlHelper.FindVisualParent<MTabControl>(this);
tabControl?.TabItemAddCommand?.Execute(url);
});
}
该方法用于新增一个Tab页。
运行看效果

六、源码地址
gitee地址:https://gitee.com/sirius_machao/mweb-browser
基于CefSharp开发(二)自定义浏览器窗体的更多相关文章
- 基于.net开发chrome核心浏览器【二】
原文:基于.net开发chrome核心浏览器[二] 一: 上一篇的链接: 基于.net开发chrome核心浏览器[一] 二: 相关资源介绍: chrome Frame: 让IE有一颗chrome的心, ...
- 基于CefSharp开发浏览器(八)浏览器收藏夹栏
一.前言 上一篇文章 基于CefSharp开发(七)浏览器收藏夹菜单 简单实现了部分收藏夹功能 如(添加文件夹.添加收藏.删除.右键菜单部分功能) 后续代码中对MTreeViewItem进行了扩展,增 ...
- 基于.net开发chrome核心浏览器【七】
这是一个系列的文章,前面六篇文章的地址如下: 基于.net开发chrome核心浏览器[六] 基于.net开发chrome核心浏览器[五] 基于.net开发chrome核心浏览器[四] 基于.net开发 ...
- 基于.net开发chrome核心浏览器
本文转载自:http://www.cnblogs.com/liulun/archive/2013/04/20/3031502.html 一: 上一篇的链接: 基于.net开发chrome核心浏览器[一 ...
- 基于.net开发chrome核心浏览器【四】
原文:基于.net开发chrome核心浏览器[四] 一: 上周去北京出差,给国家电网的项目做架构方案,每天都很晚睡,客户那边的副总也这样拼命工作. 累的不行了,直接导致第四篇文章没有按时发出来. 希望 ...
- 基于.net开发chrome核心浏览器【三】
原文:基于.net开发chrome核心浏览器[三] 本篇我们讲解怎么用CefGlue开发一个最简单的浏览器 一: CefGlue是建立在Cef项目之上的,Cef项目是C/C++的项目:CefGlue只 ...
- 基于.net开发chrome核心浏览器【一】
原文:基于.net开发chrome核心浏览器[一] 说明: 这是本系列的第一篇文章,我会尽快发后续的文章. 源起 1.加快葬送IE6浏览器的进程 世界上使用IE6浏览器最多的地方在中国 中国使用IE6 ...
- 基于.net开发chrome核心浏览器【五】
一:本篇将解决的问题 本章主要为了解决一下几个问题: 1.JsDialog的按钮错位的问题 我们开发出的浏览器,在有些操系统上调用alert,confirm之类的对话框时,确定和取消按钮会出现错位的情 ...
- 基于CefSharp开发(五)浏览器菜单样式
一.菜单分析 上图为Edge浏览器现有的菜单内容,菜单中即有子菜单也有组合菜单. 本章节将开发浏览器菜单样式,菜单部分功能将后期进行处理. 二.创建菜单用户控件 新建用户控件命名为WebMenuUc, ...
随机推荐
- 【17】进大厂必须掌握的面试题-50个Angular面试
我们整理了一份主要的Angular面试问题清单,分为三部分: 角度面试问题–初学者水平 角度面试问题–中级 角度面试问题–高级 初学者水平–面试问题 1.区分Angular和AngularJS. 特征 ...
- 服务网格istio概念应知应会
一.背景 最近架构组基于istio开发了服务网格(Service Mesh)平台,借此机会把相关的背景知识做一次学习和记录,方便回头查看. 初版的效果: 二.istio 官方手册:https://is ...
- C# 时间格式处理
C#的常用时间格式意义: 1字符"y"---year,年,yy显示13,yyyy显示2013 2字符"M"---Month,月份,M显示5,MM显示05 3字符 ...
- Inception系列之Inception_v1
目前,神经网络模型为了得到更好的效果,越来越深和越来越宽的模型被提出.然而这样会带来以下几个问题: 1)参数量,计算量越来越大,在有限内存和算力的设备上,其应用也就越难以落地. 2)对于一些数据集较少 ...
- C的输入&输出
格式说明符 输出 %d整型输出,%ld长整型输出, %o以八进制数形式输出整数, %x以十六进制数形式输出整数,或输出字符串的地址. %u以十进制数输出unsigned型数据(无符号数).注意:%d与 ...
- 记录一些API(持续更新)
//对response进行编解码URLEncoder.encode(string,"UTF-8");//ts检查checkbox是否为选中状态$event.target.check ...
- Linux 下 GCC 的使用
0 运行环境 本机系统:Windows 7 虚拟机软件:Oracle VM VirtualBox 6 虚拟机系统:CentOS 7 1 GCC 简介 GCC 是 GUN Compiler Collec ...
- centos 升级内核并安装对应kernel-devel
内核包使用ELReo提供 1.准备ELRepo (1)检测ELRepo是否安装 yum --disablerepo="*" --enablerepo="elrepo-ke ...
- No matching distribution found for Tensorflow
No matching distribution found for Tensorflow 原因:python 3.7.3 版本过高 解决:安装3.6 64位
- NAT基本原理及应用
参考链接 https://blog.csdn.net/u013597671/article/details/74275852