基于CefSharp开发(六)浏览器网页缩放
一、网页缩放分析
缩放入口
1、Ctrl + 鼠标滑轮缩放
2、菜单中缩放子菜单缩放
3、搜索框中网页缩放按钮缩放
缩放属性及命令
ChromiumWebBrowser 提供了缩放量值、缩放级别、放大/缩小/重置命令等,如下图
二、鼠标滑轮缩放
简单缩放实现
要实现缩放,首先需捕获鼠标滚动事件,在初始化WebBrowser方法中增加
this.CefWebBrowser.PreviewMouseWheel += CefWebBrowser_PreviewMouseWheel;
并实现CefWebBrowser_PreviewMouseWheel方法,这里需要判断Ctrl是否按下,代码如下:
private void CefWebBrowser_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if ((Keyboard.Modifiers & ModifierKeys.Control) != ModifierKeys.Control) return;
try
{
if (e.Delta > 0)
{
CefWebBrowser.ZoomInCommand.Execute(null);
}
else if (e.Delta < 0)
{
CefWebBrowser.ZoomOutCommand.Execute(null);
}
e.Handled = true;
}
catch (Exception ex)
{ }
}
其中e.Delta大于0时放大网页,小于0时缩小网页
页面重置
一般习惯Ctrl+0重置网页大小,故需要在CefWebBrowser_PreviewKeyDown中增加组合键处理,注意:0的key值包含小键盘(NumPad0),代码如下:
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control
&& (e.Key == Key.D0 || e.Key == Key.NumPad0))
{
CefWebBrowser.ZoomResetCommand.Execute(null);
// CefWebBrowser.SetZoomLevel(0);
}
ZoomResetCommand 可使缩放级别恢复到页面打开时的缩放级别(默认为100%,若有设置可能不是100%),强势重置到100%可使用注释代码 CefWebBrowser.SetZoomLevel(0);
三、增加缩放级别显示
上面内容已可以实现网页缩放,但不知具体缩放比例(级别),查看Edge缩放展示
当网页缩放时会在搜索框中显示缩放按钮,并在下方展示缩放小窗口,接下来实现如下内容
1、扩展搜索框
由于搜索框的内容将越来越多,故不能用通用的MTextBox,需新建一个搜索框便于以后内容扩展,新建CustomControl MSearchText,
并从MTextBox搬砖到MSearchText
MSearchText控件需要增加依赖属性ZoomLevelType用来判断缩放按钮是否显示、缩小、放大
此时需要个Menu类型,添加枚举类型 None不显示缩放
public enum ZoomType
{
None,
In,
Out,
}
增加依赖属性
public static readonly DependencyProperty ZoomLevelTypeProperty = DependencyProperty.Register("ZoomLevelType", typeof(ZoomType), typeof(MSearchText));
/// <summary>
/// ZoomLevelType 缩放类型
/// </summary>
public ZoomType ZoomLevelType
{
get => (ZoomType)GetValue(ZoomLevelTypeProperty);
set => SetValue(ZoomLevelTypeProperty, value);
}
在Xaml中Search框中增加一列 ZoomButon
<Grid Grid.Column="2">
<ToggleButton x:Name="PART_ZoomButton" FontSize="16" Style="{DynamicResource ToggleButton.FontButton}" Margin="2,0"/>
</Grid>
在触发器中增加显示状态控制
<Trigger Property="ZoomLevelType" Value="None">
<Setter TargetName="PART_ZoomButton" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="ZoomLevelType" Value="In">
<Setter TargetName="PART_ZoomButton" Property="Content" Value="" />
</Trigger>
<Trigger Property="ZoomLevelType" Value="Out">
<Setter TargetName="PART_ZoomButton" Property="Content" Value="" />
</Trigger>
2、ZoomLevelType 类型绑定
在MSearchText 中增加Binding,ViewModel这里不再赘述。
<controls:MSearchText Grid.Column="1" Watermark="搜索或输入Web地址" Text="{Binding CurrentUrl, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
ZoomLevelType="{Binding ZoomLevelType}" KeyDown="Search_OnKeyDown"/>
当页面缩放时,执行SetSearchZoomStatus方法
private void SetSearchZoomStatus()
{
if (CefWebBrowser.ZoomLevel < 0)
{
ViewModel.ZoomLevelType = ZoomType.Out;
}
else if (CefWebBrowser.ZoomLevel > 0)
{
ViewModel.ZoomLevelType = ZoomType.In;
}
else
{
ViewModel.ZoomLevelType = ZoomType.None;
}
}
运行效果:
3、 缩放小窗口
Edge缩放小窗口具有如下特点:
1、缩放比例实时更新
2、当点击缩放Button 弹出小窗口
3、Ctrl+鼠标滑轮放大缩小 小窗口几秒后消失
首先设计小窗口,采用Popup,继续扩展MSearchText,增加Popup弹窗,增加TextBlock用于显示缩放比例,三个Button分别为缩小、放大、重置
<Popup x:Name="PART_ZoomPopUp" PopupAnimation="Fade" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_ZoomButton}"
StaysOpen="{TemplateBinding ZoomStaysOpen}" AllowsTransparency="True" HorizontalOffset="-180" VerticalOffset="5" IsOpen="{TemplateBinding ZoomIsChecked}">
<Border Background="{DynamicResource WebBrowserBrushes.SearchZoomPopupBackground}" CornerRadius="5">
<DockPanel Width="251" Height="40">
<TextBlock Text="{TemplateBinding ZoomRatio}" VerticalAlignment="Center" Margin="15,0,0,0" HorizontalAlignment="Left"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,15,0">
<Button Content="" Style="{DynamicResource Button.FontButton}" Width="26" Height="26"/>
<Button Content="" Style="{DynamicResource Button.FontButton}" Margin="10,0,0,0" Width="26" Height="26"/>
<Button Content="重置" Style="{DynamicResource Button.FontButton}" Margin="10,0,0,0" Width="64" Background="{DynamicResource WebBrowserBrushes.SearchZoomPopupResetBackground}"/>
</StackPanel>
</DockPanel>
</Border>
</Popup>
Popup的 PlacementTarget指向缩放按钮。此时缩放按钮代码如下:
<ToggleButton xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x:Name="PART_ZoomButton" FontSize="16"
Style="{DynamicResource ToggleButton.FontButton}" IsChecked="{TemplateBinding ZoomIsChecked}" Margin="2,0"/>
根据特点1,需要添加依赖属性ZoomRatio用于实时刷新比例,
根据特点2 和特点3 缩放按钮的选中状态需控制,故增加依赖属性 ZoomIsChecked,
同时需要控制Popup的显示是否保持显示状态,故增加依赖属性 ZoomStaysOpen,
在ViewModel中同样需要增加上述属性(非依赖属性)
接着对MSearchText使用处建立绑定如下:
<controls:MSearchText Grid.Column="1" Watermark="搜索或输入Web地址" Text="{Binding CurrentUrl, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
ZoomLevelType="{Binding ZoomLevelType}" ZoomRatio="{Binding ZoomRatio}" ZoomIsChecked="{Binding ZoomIsChecked}"
ZoomStaysOpen="{Binding ZoomStaysOpen}" KeyDown="Search_OnKeyDown"/>
4、后端代码控制
扩展SetSearchZoomStatus方法,增加对选中状态及显示比例(显示比例做了简单处理,并不完全正确)的控制
private void SetSearchZoomStatus()
{
if (CefWebBrowser.ZoomLevel < 0)
{
ViewModel.ZoomLevelType = ZoomType.Out;
ViewModel.ZoomIsChecked = true;
if (CefWebBrowser.ZoomLevel > -1)
{
ViewModel.ZoomRatio = "90%";
}
else if (CefWebBrowser.ZoomLevel <= 1)
{
var radio = Math.Round((CefWebBrowser.ZoomLevel + 5) / 5 * 100);
ViewModel.ZoomRatio = $"{radio}%";
}
}
else if (CefWebBrowser.ZoomLevel > 0)
{
ViewModel.ZoomLevelType = ZoomType.In;
ViewModel.ZoomIsChecked = true;
var radio = Math.Round((1 + CefWebBrowser.ZoomLevel) * 100, 2);
ViewModel.ZoomRatio = $"{radio}%";
}
else
{
ViewModel.ZoomLevelType = ZoomType.None;
ViewModel.ZoomIsChecked = false;
} }
接着增加定时器,在鼠标滑轮放大时启动定时器,用于判断Popup是否消失,
此处用一变量_zoomWaitingCount判断是否隐藏,如持续滚动滑动则_zoomWaitingCount重新计数
private void CefWebBrowser_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if ((Keyboard.Modifiers & ModifierKeys.Control) != ModifierKeys.Control)
{
ViewModel.ZoomStaysOpen = false;
return;
}
try
{
_zoomWaitingCount = 0;
if (e.Delta > 0)
{
if (this.CefWebBrowser.ZoomLevel < 4)
{
CefWebBrowser.ZoomInCommand.Execute(null);
}
ViewModel.ZoomStaysOpen = true;
}
else if (e.Delta < 0)
{
if (this.CefWebBrowser.ZoomLevel > -4)
{
CefWebBrowser.ZoomOutCommand.Execute(null);
}
ViewModel.ZoomStaysOpen = true;
}
_zoomToolTimer.Elapsed -= ZoomToolTimer_Elapsed;
_zoomToolTimer.Elapsed += ZoomToolTimer_Elapsed;
_zoomToolTimer.AutoReset = true;
_zoomToolTimer.Enabled = true;
SetSearchZoomStatus();
e.Handled = true;
}
catch (Exception ex)
{ }
} private void ZoomToolTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (_zoomWaitingCount > 2)
{
_zoomToolTimer?.Stop();
ViewModel.ZoomIsChecked = false;
ViewModel.ZoomStaysOpen = false;
_zoomWaitingCount = -1;
return;
} if (_zoomWaitingCount > -1)
{
_zoomWaitingCount++;
}
}
运行效果:
小弹窗按钮命令绑定这里不再赘述,详情请查看代码
四、源码地址
gitee地址:https://gitee.com/sirius_machao/mweb-browser
基于CefSharp开发(六)浏览器网页缩放的更多相关文章
- 基于CefSharp开发浏览器(八)浏览器收藏夹栏
一.前言 上一篇文章 基于CefSharp开发(七)浏览器收藏夹菜单 简单实现了部分收藏夹功能 如(添加文件夹.添加收藏.删除.右键菜单部分功能) 后续代码中对MTreeViewItem进行了扩展,增 ...
- mac 下基于firebreath 开发多浏览器支持的浏览器插件
mac 下基于firebreath 开发多浏览器支持的浏览器插件 首先要区分什么是浏览器扩展和浏览器插件;插件可以像本地程序一样做的更多 一. 关于 firebreath http://www.fir ...
- 基于CefSharp开发(二)自定义浏览器窗体
上一篇 https://www.cnblogs.com/mchao/p/13914726.html 简单了解了CefSharp引用配置但页面光秃秃的,这一篇着手开发简单浏览器窗体 一.Edge浏览器窗 ...
- 基于CefSharp开发(五)浏览器菜单样式
一.菜单分析 上图为Edge浏览器现有的菜单内容,菜单中即有子菜单也有组合菜单. 本章节将开发浏览器菜单样式,菜单部分功能将后期进行处理. 二.创建菜单用户控件 新建用户控件命名为WebMenuUc, ...
- 基于CefSharp开发(四)浏览器文件下载
一.CefSharp文件下载分析 查看ChromiumWebBrowser类发现cef数据下载处理在IDownloadHandler中进行,但并未找到相应的实现类,故我们需要自己实现DownloadH ...
- 基于CefSharp开发(七)浏览器收藏夹菜单
一.Edge收藏夹菜单分析 如下图所示为Edge收藏夹菜单, 点击收藏夹菜单按钮(红框部分)弹出收藏夹菜单窗体,窗体中包含工具栏(绿框部分)和树型菜单(黄框部分) 工具栏按钮功能分别为添加当前网页到根 ...
- 基于CefSharp开发(三)浏览器头部优化
一.上文回顾 上编实现了简单的网页加载功能包括URL输入.打开空标签页.网页链接中新页面处理等 本编将对网页的Title绑定.前进.后退.刷新等事件处理 二.Title绑定处理 当打开网页时Title ...
- 基于CefSharp开发浏览器(九)浏览器历史记录弹窗面板
一.前言 前两篇文章写的是关于浏览器收藏夹的内容,因为收藏夹的内容不会太多,故采用json格式的文本文件作为收藏夹的存储方式. 关于浏览器历史记录,我个人每天大概会打开百来次网页甚至更多,时间越长历史 ...
- 基于cefsharp的用户浏览器
技术:vc++2015 概述 用于需要制作一个浏览器 winfrom 中浏览器的插件有很多种 如:WebBrowser , Web.kit等 但用于比较稳定 功能齐全的还是cefsharp 详细 ...
随机推荐
- MySQL 使用规范总结
MySQL已经成为世界上最受欢迎的数据库管理系统之一,无论是用在小型开发项目上,还是用在构建那较大型的网站,MySQL都用实力证明了自己是一个稳定.可靠.快速.可信的系统,足以胜任任何数据存储业务的需 ...
- C++ 数据结构 2:栈和队列
1 栈 1.1 栈的基本概念 栈(stack)又名堆栈,它是一种 运算受限的线性表.限定 仅在表尾进行插入和删除操作 的线性表.表尾被称为栈顶,相对地,把另一端称为栈底. 1.1.1 特点 它的特殊之 ...
- 【JVM第八篇--垃圾回收】GC和GC算法
写在前面的话:本文是在观看尚硅谷JVM教程后,整理的学习笔记.其观看地址如下:尚硅谷2020最新版宋红康JVM教程 1.垃圾 1.1.什么是垃圾 垃圾(Garbage)在Java语言中是指在运行程序中 ...
- MySql Binlog 说明 & Canal 集成MySql的更新异常说明 & MySql Binlog 常用命令汇总
文章来源于本人的印象笔记,如出现格式问题可访问该链接查看原文 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录 背景介绍 开启MySq ...
- rbd的image快照与Pool快照
前言 这个问题是不久前在ceph社区群里看到的,创建image的时候,当时的报错如下: 2016-12-13 23:13:10.266865 7efbfb7fe700 -1 librbd::image ...
- 使用phpExcel读取excel文件
include_once '../include/common.inc.php'; include_once MC_ROOT.'include/smarty.inc.php'; date_defaul ...
- kali linux与虚拟机Vmware安装vmware tools(主机与虚拟机的文件拖拽)
一.打开虚拟机任务栏"虚拟机"-----点击安装Vmware tools 二.回到开启的kali linux系统中,找到vmware tools CD文件夹,拖拽出文件中的压缩文件 ...
- 思维导图软件iMindMap制作技巧有哪些
iMindMap11是iMindMap全新的版本.它可以提供给我们更好的灵活性以便我们将我们的思维进行可视化,并进一步的呈现和开发出属于自己的想法以及思维方式.在iMindMap中我们可以利用思维导图 ...
- MathType总结编辑括号的类型(下)
在数学中,所涉及到的公式总是会有各种各样的情况,对于括号这些都是最常见的了.在最开始的四则基本运算中我们学会了使用括号,而随着学习的不断深入,所涉及到的符号与公式都越来越多,对于括号的类型也是使用得非 ...
- Guitar Pro 7教程之打开播放文件的操作技巧
前面的章节我们讲过了很多关于Guitar Pro的相关教程,由于最近{cms_selflink page='index' text='Guitar Pro'} 7中文版刚上新没多久,很多玩吉他的小伙伴 ...