基于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 详细 ...
随机推荐
- Docker - 解决 gitlab 容器上的项目进行 clone 时,IP 地址显示一串数字而不是正常 IP 地址的问题
问题背景 通过 gitlab 容器创建了一个项目,想 clone 到本地,结果发现项目的 IP 地址是一串数字 问题排查 明明创建项目的时候,IP 地址还是正常的鸭! 再看看项目的 settings ...
- k8s event监控利器kube-eventer对接企微告警
背景 监控是保障系统稳定性的重要组成部分,在Kubernetes开源生态中,资源类的监控工具与组件监控百花齐放. cAdvisor:kubelet内置的cAdvisor,监控容器资源,如容器cpu.内 ...
- Spider--动态网页抓取--审查元素
# 静态网页在浏览器中展示的内容都在HTML的源码中,但主流网页使用 Javascript时,很多内容不出现在HTML的源代码中,我们需要使用动态网页抓取技术. # Ajax: Asynchronou ...
- CentOS修改镜像源头
CentOS6改为阿里镜像源: 1. cd /etc/yum.repos.d 2. mv CentOS-Base.repo CenOS-Base.repo.bak 3. wget http://mir ...
- Failed connect to mirrors.cloud.aliyuncs.com:80
在yum insatall 安装是报错 Failed connect to mirrors.cloud.aliyuncs.com:80; Connection refused 解决方法: cd /et ...
- 链路层输出 -qdisc
二层发送中,实现qdisc的主要函数是__dev_xmit_skb和net_tx_action,本篇将分析qdisc实现的原理,仅对框架进行分析. 其框架如下图所示 qdisc初始化 pktsched ...
- 源码分析:ReentrantReadWriteLock之读写锁
简介 ReentrantReadWriteLock 从字面意思可以看出,是和重入.读写有关系的锁,实际上 ReentrantReadWriteLock 确实也是支持可重入的读写锁,并且支持公平和非公平 ...
- pycharm 报错及解决方法
1.报错: AttributeError: 'list' object has no attribute 'click' 原因:应是find_element_by 不是 find_elements_b ...
- 缩点Tarjan算法解析+[题解]受欢迎的牛
(注:我在网上找了一些图,希望原博主不要在意,谢谢,(。☉౪ ⊙。)) 首先来了解什么是强连通分量 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向 ...
- NAT基本原理及应用
参考链接 https://blog.csdn.net/u013597671/article/details/74275852