基于CefSharp开发(三)浏览器头部优化
一、上文回顾
上编实现了简单的网页加载功能包括URL输入、打开空标签页、网页链接中新页面处理等
本编将对网页的Title绑定、前进、后退、刷新等事件处理
二、Title绑定处理
当打开网页时Title一直是新标签页,而Edge浏览器中是动态变化的,因此我们需要建立起绑定机制,那么如何取网页Title?
查看ChromiumWebBrowser 类定义
public static readonly DependencyProperty TitleProperty;
发现其有Title的依赖属性,并在类定义中找到了 TitleChanged事件
public event DependencyPropertyChangedEventHandler TitleChanged;
因此只要将Tab页的Header属性与ChromiumWebBrowser类中的Title建立起关系就可以
创建 WebTabItemViewModel 添加 Header属性
public class WebTabItemViewModel: BaseViewModel { private string _title = "新标签页";
public string Title{ get =>_title ; set { _title = value; OnPropertyChanged("Title"); } }
}
在TitleChanged 改变时赋值给Header
private void CefWebBrowser_TitleChanged(object sender, DependencyPropertyChangedEventArgs e) { ViewModel.Title= CefWebBrowser.Title; }
并在新打开Tab页时建立绑定
private void TabItemAdd(object obj) { try { var uc = new WebTabItemUc { TargetUrl = obj?.ToString() }; var item = new TabItem { Content = uc }; var bind = new Binding { Source = uc.DataContext, Path = new PropertyPath("Header") }; item.SetBinding(HeaderedContentControl.HeaderProperty, bind); WebTabControl.Items.Add(item); WebTabControl.SelectedItem = item; WebTabControl.SetHeaderPanelWidth(); } catch (Exception ex) { } }
此处可以直接绑定ChromiumWebBrowser 的Title属性,但为了能使当打开新Tab页时显示【新标签页】所以做了个ViewModel处理
运行看下效果
此时Title还缺个Favicon,Favicon 格式为协议+域名+端口+/favicon.ico
如百度https://www.baidu.com/favicon.ico
故增加favicon获取方法
private ImageSource GetFavicon() { try { var pattern = @"(\w+:\/\/)([^/:]+)(:\d*)?"; var address = CefWebBrowser.Address; var matches = Regex.Matches(address, pattern); return matches.Count <= 0 ? null : ImageHelper.GetBitmapFrame($"{matches[0]}/favicon.ico"); } catch (Exception e) { return ImageHelper.DefaultFavicon; } }
public static ImageSource GetBitmapFrame(string httpUrl) { try { return string.IsNullOrEmpty(httpUrl) ? DefaultFavicon : BitmapFrame.Create(new Uri(httpUrl), BitmapCreateOptions.None, BitmapCacheOption.Default); } catch { return DefaultFavicon; }
并暂时将此方法加到Browser Title改变事件中
private void CefWebBrowser_TitleChanged(object sender, DependencyPropertyChangedEventAr 1b14 gs e) { ViewModel.Title = CefWebBrowser.Title; ViewModel.Favicon = GetFavicon(); }
接下来需要对ViewModel中Favicon 进行界面绑定关联
此时需要对Tabitem进行扩展这里使用附加属性来绑定Favicon
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="auto"/> </Grid.ColumnDefinitions> <Image x:Name="PART_Favicon" Grid.Column="0" Source="{TemplateBinding attached:AttachedPropertyClass.ImageSource}" Width="18" Height="18"/> <ContentPresenter Grid.Column="1" x:Name="contentPresenter" ContentSource="Header" Focusable="False" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"> <ContentPresenter.Resources> <Style TargetType="{x:Type TextBlock}"> <Setter Property="FontSize" Value="14"/> <Setter Property="TextTrimming" Value="CharacterEllipsis"/> <!--不知为什么直接在tabitem中设置fontsize不起作用--> </Style> </ContentPresenter.Resources> </ContentPresenter> <Button Grid.Column="2" Style="{StaticResource TabCloseButton}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MTabControl}},Path=TabItemRemoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}" /> </Grid>
Xaml中 PART_Favicon 绑定附加属性 ImageSource接下来对附加属性与ViewModel中的Favicon进行绑定
在TabItemAdd方法中增加绑定
private void TabItemAdd(object obj) { try { var uc = new WebTabItemUc { ViewModel = { CurrentUrl = obj?.ToString() } }; var item = new TabItem { Content = uc }; var titleBind = new Binding { Source = uc.DataContext, Path = new PropertyPath("Title") }; item.SetBinding(HeaderedContentControl.HeaderProperty, titleBind); var faviconBind = new Binding { Source = uc.DataContext, Path = new PropertyPath("Favicon") }; item.SetBinding(AttachedPropertyClass.ImageSourceProperty, faviconBind); WebTabControl.Items.Add(item); WebTabControl.SelectedItem = item; WebTabControl.SetHeaderPanelWidth(); } catch (Exception ex) { } }
再次运行程序
三、前进、后退、刷新处理
前进、后退、刷新是IWebBrowser的扩展方法 在WebBrowserExtensions类中
分别添加按钮的响应事件如下
private void NavigationForward_OnClick(object sender, RoutedEventArgs e) { this.CefWebBrowser.Forward(); } private 56c void NavigationBack_OnClick(object sender, RoutedEventArgs e) { this.CefWebBrowser.Back(); } private void NavigationRefresh_OnClick(object sender, RoutedEventArgs e) { this.CefWebBrowser.Reload(); }
绑定前进后退按钮可用状态 分别为CanGoForward、CanGoBack
<StackPanel Grid.Column="0" Orientation="Horizontal" x:Name="NavigationStackPanel"> <Button Style="{DynamicResource Button.NavigationBack}" IsEnabled="{Binding CanGoBack}" Click="NavigationBack_OnClick"/> <Button Style="{DynamicResource Button.NavigationForward}" IsEnabled="{Binding CanGoForward}" Click="NavigationForward_OnClick"/> <Button Style="{DynamicResource Button.NavigationRefresh}" Click="NavigationRefresh_OnClick"/> </StackPanel>
在cs代码中进行 NavigationStackPanel的上下文绑定
NavigationStackPanel.DataContext = CefWebBrowser;
此处我们直接绑定ChromiumWebBrowser 的依赖属性,故DataContext赋值为 CefWebBrowser
四、源码地址
- 基于Cef的简易浏览器开发(CefSharp)
- 基于CefSharp开发(四)浏览器文件下载
- 基于Cef的简易浏览器开发(CefSharp)
- 基于内嵌浏览器内核(如XULRunner、CEF)来开发桌面软件
- 本人用VC开发的基于浏览器的票据打印控件
- html移动Web开发----优化浏览器视口宽度设置
- 第十一章 设计用户界面 之 基于浏览器优化程序行为和样式
- 在基于vue的webpack脚手架开发中使用了代理转发,结果浏览器发出的请求中不带cookie导致登录时总是session失效怎么办?
- 数据库访问性能优化 特别说明: 1、 本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识; 2、 本文许多示例及概念是基于Oracle数据库描述
- 基于.net开发chrome核心浏览器
- 在 .NET 中开发基于 Chrome 内核的浏览器-创建一个简单浏览器 分类: C# 2014-10-27 16:27 594人阅读 评论(0) 收藏
- 网络爬虫项目开发日志(七): 基于MD5去重树的爬虫设计与优化
- 移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析html代码,更好地将移动web前端页面表现出来。本文整理一些常用的meta标签
- OA++中基于Notes平台上浏览器的开发
- 基于.net开发chrome核心浏览器【五】
- SharpStreaming项目开发纪实:构建基于RTSP协议的服务器及客户端应用——准备知识(RTSP协议)
- EEPlat的基于浏览器的在线开发技术
- 详解如何解决vue开发请求数据跨域的问题(基于浏览器的配置解决)
- QuickCSharp框架开发(2)-基于角色的安全访问控制系统存储过程设计
- 在 .NET 中开发基于 Chrome 内核的浏览器-创建一个简单浏览器 分类: C# 2014-10-27 16:27 593人阅读 评论(0) 收藏