对现代化Windows桌面应用而言,越来越多的应用程序采用Hybrid混合架构,即原生客户端技术+Web网页技术嵌入的混合模式提供应用服务,这样既有原生技术先天的端能力优势,又有来自Web技术的快速开发、灵活部署的优势。
目前主流的方案肯定是"基于嵌入式Chromium框架(简称CEF)"解决方案,但是带来的问题就是程序安装包体积巨大,因为它必须要把整个Chromium内核完整的打包进去,而微软原生控件WebView或者WebBrowser控件由于其技术或背后浏览器框架跟不上现代步伐,很难满足实际场景需求,那么随着MicrosoftEdge积极采用Chromium内核,并被Windows10/11内置,基于它诞生了WebView2这个控件,未来我们有希望可以直接通过使用WebView2来替代CEF,从而大幅降低混合架构开发模式下的安装包体积,提高程序运行效率。
采用WebView2的核心优势:1、缩小应用程序安装包体积大小。2、降低应用程序磁盘空间占用。3、节约Hybrid架构开发实现成本。4、减少应用分发的CDN流量消耗。5、优化浏览器运行内核维护成本。
核心提要:1、从Windows11开始的操作系统版本将直接内置WebView2运行时;2、Microsoft365应用程序v2101版本已开始依赖WebView2运行时提供和Web无差体验的新功能和特性;3、截止到目前,WebView2运行时已被超过2亿台Windows设备部署。4、WebView2运行时自带对H264编码的支持,无需额外编译配置。
MicrosoftEdgeWebView2控件允许在本机应用中嵌入Web技术(HTML、CSS以及JavaScript)。WebView2控件使用MicrosoftEdge(Chromium)作为绘制引擎,以在本机应用中显示Web内容。使用WebView2,可以在本机应用的不同部分嵌入Web代码,或在单个WebView实例中生成所有本机应用。
"WebView2运行时(Webview2Runtime)"是一个可再发行运行时,并充当WebView2(或)Web平台的基础组件。此概念类似于VisualC++/.NET应用的.NET运行时。"WebView2运行时"包含经过修改的MicrosoftEdge(Chromium)二进制文件,这些二进制文件针对WebView2应用进行了微调和测试。安装WebView2运行时后,它不会显示为用户可见的浏览器应用。例如,用户没有浏览器桌面快捷方式或"开始"菜单中的条目。
有两种不同的方法将"WebView2运行时"分发和更新到客户端计算机:常青分发模式和离线分发模式。
在“常青分发模式(EvergreenRuntime)”下,WebView2运行时不与你的应用打包,但最初使用联机引导程序或脱机安装程序安装到客户端上。之后,WebView2运行时将在客户端计算机上自动更新。然后,你可以从最新的WebView2SDK分发使用最新WebView2API的WebView2应用更新。建议大多数开发人员使用常青分发模式。
优点:
缺点:
在“离线分发模式(OfflineRuntime)”下,下载特定版本的WebView2运行时,并随应用包中的WebView2应用一起打包它。随应用打包的WebView2运行时仅由WebView2应用使用,而客户端计算机上任何其他应用不会使用。
我们一直在努力提高WebView2运行时在Windows机器上的可用性。我们很高兴地宣布这项工作的两项更新。首先,WebView2运行时将在Windows11机器中内置。其次,我们看到许多应用程序,包括MicrosoftOffice,开始将WebView2Runtime与其应用程序一起部署。迄今为止,WebView2Runtime已安装在超过2亿台Windows设备上!WebView2Runtime的日益普及将使以首选的Evergreen分发模式部署WebView2应用程序变得更加容易。
Microsoft365应用开始提供依赖"WebView2运行时(Webview2Runtime)"的新功能或改进功能。例如,Outlook中的会议室查找器和会议Insights功能。WebView2是MicrosoftEdge使用的渲染引擎,在桌面应用程序中显示基于Web的功能。
通过使用"WebView2运行时(Webview2Runtime)",我们可以更轻松地为您的用户提供跨设备平台外观和感觉相同的Office功能。反过来,这种一致的体验可帮助您的用户学习和使用这些功能,而无需了解每个设备平台上Office的细微差别。
例如,通过使用"WebView2运行时(Webview2Runtime)",在运行Windows的设备上使用Outlook和在Web上使用Outlook时,房间查找器功能看起来相同。Office加载项也将开始依赖"WebView2运行时(Webview2Runtime)"。
WebView2要求在运行Office的设备上安装"WebView2运行时(Webview2Runtime)"。如果设备上未安装"WebView2运行时(Webview2Runtime)",您的用户将无法使用依赖于WebView2的Office功能。
因此,在2021年4月,我们开始在运行Windows且安装了Microsoft365应用程序版本2101或更高版本的设备上安装"WebView2运行时(Webview2Runtime)"。
重要
1.新建名为"HelloWebView2"的解决方案
2.切换到"HelloWebView2"目录
1.创建名为"demoForWpfCore"的Wpf项目
2.添加"demoForWpfCore"到解决方案
3.切换到"demoForWpfCore"目录
4.运行"demoForWpfCore"项目
1.添加WinUI3的空白项目
在解决方案上右键,添加=>新建项目,筛选C#语言,Windows平台,WinUI项目类型。
选择"打包的空白应用(桌面版WinUI3)(BlankApp,Packaged(WinUI3indesktop))"项目类型,然后单击"下一步"按钮。
创建名为demoForWinUi3的项目。
创建成功之后,会发现多了两个项目,一个是demoForWinUi3桌面项目,一个是demoForWinUi3(Package)打包项目。
1.创建名为"demoForWinFormFrame"的WinForms项目
这里需要将框架最低设置为:.NetFramework4.5,这是目前WebView2的WinFroms包最低兼容版本。
2.运行"demoForWinFormFrame"项目
在demoForWinFormFrame项目右键进入"管理Nuget程序包"。
搜索关键词WebView2即可找到Microsoft.Web.WebView2这个包,安装即可。
双击打开MainForm.cs文件,打开窗体设计视图。
在VisualStudio顶部菜单的"视图"=>"工具栏",这时候我们会看到顶部会多出来一个WebView2WindowsFormsControl组,里面有个控件叫WebView2控件。
接下来,我们运行看看效果
1.使用字体图标来构建按钮,准备字体资源
首先,我们还是需要引入SegoeFluentIcons.ttf这个字体图标文件,我们把它放在根目录的Fonts文件夹中,生成操作需设置成"内容",复制到输出目录设置为"始终复制"。
然后我们需要借助一个IconfontHelper的类来读取字体资源。
publicclassIconfontHelper{//提供一个字体系列集合,该集合是基于客户端应用程序提供的字体文件生成的。privatestaticSystem.Drawing.Text.PrivateFontCollectionpfcc;publicstaticSystem.Drawing.Text.PrivateFontCollectionPFCC{get{returnpfccLoadFont();}}publicstaticSystem.Drawing.Text.PrivateFontCollectionLoadFont(){pfcc=newSystem.Drawing.Text.PrivateFontCollection();pfcc.AddFontFile(Environment.CurrentDirectory+"/Fonts/SegoeFluentIcons.ttf");returnpfcc;}}2.实验性的在WinForms上支持字体图标,并构建按钮
我们先尝试通过Panel+Label的组合来实现一个字体图标的按钮效果。
从左侧工具箱中拖取两个控件组合成上诉截图效果,然后在MainForm的Load函数中,我们需要给Label挂载图标字体和指定图标。
publicMainForm(){InitializeComponent();Load+=MainForm_Load;}privatevoidMainForm_Load(objectsender,EventArgse){InitButtonStyle();}具体初始化按钮样式的方法如下:
///
效果还算让人满意。
然后选中前面的SegoeFluentIcons.ttf文件上传并解析,然后它会把字体中所有图标的Unicode编码展示出来,这里我们以前进和后退两个图标为例,我们会看到他们的编码都是以开头和;结尾的,我们只需要提取剩下的字符,加上前缀\ue即可,比如前进按钮编码而言,最终的编码为\ue0ab,依次类推即可。
我们知道,Win10是直角风格,但是Win11开始微软开始推行圆角,甚至默认窗体,你原来是直角的都会自动给你加成圆角。
那么我们也想办法来构建一组圆角的控件,查了一些资料,说实话没有找到特别满意的方案,最终找了个妥协的,那就是依靠绘制来做的一个圆角Panel来构建控件的圆角,它还有个缺点就是不太方便去改变颜色了。
基于它,我们结合Label和TextBox这两个自带控件,分别组建自定义控件LabelButton和CornerTextbox,都用这个CornerRadiusPanel做圆角的底盘。
控件的相对位置可能需要耐心的调整,为了更加精致一点,这里我们的LabelButton控件采用45x45的尺寸,CornerTextbox控件采用603x50的尺寸,其中内嵌的TextBox字体大小采用20pt。
a.命令行安装"Microsoft.Web.WebView2"
b.或者项目右键Nuget包管理,通过可视化界面安装"Microsoft.Web.WebView2"
c.安装之前,Bin目录结构
d.安装之后,Bin目录结构
发现,新增了Microsoft.Web.WebView2.Core.dll、Microsoft.Web.WebView2.WinForms.dll、Microsoft.Web.WebView2.Wpf.dll这三个文件。
e.安装之后,运行效果
f.命令行打开项目位置
在demoForWpfCore项目的MainWindow.xaml文件中。
1.新增引用"Microsoft.Web.WebView2.Wpf"的命名空间
xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"2.添加"WebView2"控件即可,其中"Source"便是启动时加载的网址设定
1.添加Gird布局,将WebView和操作面板上下拆分
这里我们为了美观一点,采用Border包起来,并且设置一定的圆角,而且采用Gird来做左右布局。
实际效果如下:
3.程序启动的时候,自动把当前WebView的网址填写到网址输入框中
publicMainWindow(){InitializeComponent();Loaded+=MainWindow_Loaded;}privatevoidMainWindow_Loaded(objectsender,RoutedEventArgse){TextBoxForSource.Text=WebViewForMain.Source.ToString();}4.响应导航按钮的BorderForNavi_MouseDown点击事件
privatevoidBorderForNavi_MouseDown(objectsender,MouseButtonEventArgse){varsourceContext=TextBoxForSource.Text.Trim();WebViewForMain.CoreWebView2.Navigate(sourceContext);}这里需要用到WebView控件实例的CoreWebView2对象的Navigate方法。
5.响应地址输入框的TextBoxForSource_KeyDown回车事件
通常,根据用户的使用习惯,我们输入新的地址后会习惯性的回车,那么我们支持下这个习惯,增加对"地址输入框"的回车事件支持,这里运用控件"按键触发(KeyDown)"事件来做,判断e.Key==Key.Enter的情况即表示触发了回车事件。
privatevoidTextBoxForSource_KeyDown(objectsender,KeyEventArgse){if(e.Key==Key.Enter){BorderForNavi_MouseDown(null,null);}}6.优化窗体启动位置、窗体大小和名称
修改地址栏内容并回车
a.新建名为demoForWpfCoreModernUI的Wpf的.NetCore5.0的项目
b.修改demoForWpfCoreModernUI项目的目标框架
这里你可能会问,为什么要改这个?嗯,我试过,如果TargetFramework是net5.0-windows的时候,安装ModernWpfUI这个组件会跑不起来。
所以,这里我们也将demoForWpfCoreModernUI项目的目标框架修改为这个net5.0-windows10.0.18362.0。
实际上,要在Wpf里面开启对Mica的支持是不需要用到它的,但是作者说,要实现对黑暗模式的响应,所以这里用到ModernWpfUI包。
注意,只有改了前面的TargetFramework为net5.0-windows10.0.18362.0,这里的依赖项才是干净的,否则你会看到ModernWpfUI下面还有一个Microsoft.Windows.SDK.Contracts,这也是WinRT不被支持的根源。
接下来,我们需要在App.xaml中引入ModernWpfUI的样式资源。
enumDWMWINDOWATTRIBUTE{DWMWA_NCRENDERING_ENABLED=1,//[get]Isnon-clientrenderingenabled/disabled[...]+DWMWA_USE_HOSTBACKDROPBRUSH,//[set]BOOL,Allowstheuseofhostbackdropbrushesforthewindow.+DWMWA_USE_IMMERSIVE_DARK_MODE=20,//[set]BOOL,Allowsawindowtoeitherusetheaccentcolor,ordark,accordingtotheuserColorModepreferences.+DWMWA_WINDOW_CORNER_PREFERENCE=33,//[set]WINDOW_CORNER_PREFERENCE,Controlsthepolicythatroundstop-levelwindowcorners+DWMWA_BORDER_COLOR,//[set]COLORREF,Thecolorofthethinborderaroundatop-levelwindow+DWMWA_CAPTION_COLOR,//[set]COLORREF,Thecolorofthecaption+DWMWA_TEXT_COLOR,//[set]COLORREF,Thecolorofthecaptiontext+DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,//[get]UINT,widthofthevisibleborderaroundathickframewindow[...]+DWMWA_MICA_EFFECT=1029,//[set]BOOL,undocumentedDWMWA_LAST};前往MainWindow.xaml.cs文件,新增如下部分:
usingSystem.Runtime.InteropServices;usingSystem.Windows.Interop;e.重写Window窗体的WindowChrome
我们需要在MainWindow.xaml文件中,新增对WindowChrome.WindowChrome的重写。
效果还行,其实我验证过,那个黑暗模式的下,效果出不来,具体为啥还没弄清楚,总之就是没透。
g.结合前面的WebView2导航加持
由于WinUI3中已经内置了WebView2控件了,所以我们不许额外安装任何包就可以直接使用。
我们改造下HelloWinUI3桌面项目的MainWindow.xaml文件。
然后先编译一次项目,随后可以启动部署试试,看看运行效果。
为了更好的展示WebView2的能力,我们直接复制Demo4Window的已有能力好了。
目前WinUI控件提供的事件和能力还不够完善,所以部分效果暂时屏蔽和替换了。
其中:
这里我们去提取一个来用,这里需要用到一个工具,叫IconViewer。
安装之后,啥动静也没有,但是实际已经有用了。
我们找到我们要提取的目标exe,嗯嗯,肯定是带图标的那个,我们就要提取他的图标哈。
选中它,然后右键属性。
如果安装顺利,这里会多出一个Icons的标签,我们切过去,哈哈,惊喜来了,这里显示了它的图标,我们还可以选图标的大小,毫无疑问,选最大的那个,点击那个保存按钮就可以了。
接下来,我们就顺利得到一个超高清的Ico图标了。
在项目上右键,打开项目"属性",然后找到"图标和清单"部分,浏览我们刚刚保存那个图标即可。
运行一看,哈哈,已经生效了。
很香吧。
在网页导航期间,WebView2控件将引发事件。承载WebView2控件的应用侦听以下事件。
发生错误时,将引发以下事件,并可能依赖于导航到错误网页。
如果发生HTTP重定向,则一行NavigationStarting中有多个事件。
publicDemo2Window(){InitializeComponent();WebViewForMain.NavigationCompleted+=WebViewForMain_NavigationCompleted;}privatevoidWebViewForMain_NavigationCompleted(objectsender,Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgse){if(e.IsSuccess){TextBoxForSource.Text=WebViewForMain.Source.ToString();}}在Demo2Window窗体构造函数中注册WebViewForMain控件的"导航完成(NavigationCompleted)"事件,在WebViewForMain_NavigationCompleted事件处理函数中,如果NavigationCompletedEventArgs事件参数是成功状态,那么将当前WebView实例的源地址更新到地址输入框中。
从首页点击页面内的链接,跳转到其他页面之后,地址栏也会同步更新,显示当前地址。
有了前面的"导航开始(NavigationStarting)"事件和"导航完成(NavigationCompleted)"事件加持,我们便可以基于它们,提示用户正在加载了。
a.添加一个进度指示器控件ProgressBar
privatebool_isNavigationProgress;publicboolIsNavigationProgress{get{return_isNavigationProgress;}set{_isNavigationProgress=value;GirdForProgress.IsEnabled=value;GirdForProgress.IsIndeterminate=value;GirdForProgress.Visibility=valueVisibility.Visible:Visibility.Collapsed;}}在IsNavigationProgress变量的Set操作中,我们同步控制GirdForProgress的IsEnabled属性、IsIndeterminate属性、Visibility属性。
c.基于事件控制IsNavigationProgress变量值
d.运行演示效果
publicDemo4Window(){InitializeComponent();WebViewForMain.KeyDown+=WebViewForMain_KeyDown;}privatevoidWebViewForMain_KeyDown(objectsender,KeyEventArgse){if(e.IsRepeat)return;boolctrl=e.KeyboardDevice.IsKeyDown(Key.LeftCtrl)||e.KeyboardDevice.IsKeyDown(Key.RightCtrl);boolalt=e.KeyboardDevice.IsKeyDown(Key.LeftAlt)||e.KeyboardDevice.IsKeyDown(Key.RightAlt);boolshift=e.KeyboardDevice.IsKeyDown(Key.LeftShift)||e.KeyboardDevice.IsKeyDown(Key.RightShift);if(e.Key==Key.N&&ctrl&&!alt&&!shift){newMainWindow().Show();e.Handled=true;}elseif(e.Key==Key.W&&ctrl&&!alt&&!shift){Close();e.Handled=true;}}在Demo4Window窗体构造函数中注册WebViewForMain控件的"按键按下(KeyDown)"事件,在WebViewForMain_KeyDown事件处理函数中,如果KeyEventArgs事件参数中是Ctrl+N的组合,那么就新建一个窗口,如果是Ctrl+W的组合,那么就关闭当前窗口,这个快捷键和目前MicrosoftEdge是一致的。
asyncvoidInitializeAsync(){//确保WebView对象已经初始化完成awaitWebViewForMain.EnsureCoreWebView2Async(null);//监听来自WebView的消息WebViewForMain.CoreWebView2.WebMessageReceived+=CoreWebView2_WebMessageReceived;}privatevoidCoreWebView2_WebMessageReceived(objectsender,Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgse){//试图以String的方式接收消息内容varmessageContent=e.TryGetWebMessageAsString();//以系统弹窗的方式展示消息内容MessageBox.Show(messageContent);}在WebView2实例的CoreWebView2对象的EnsureCoreWebView2Async方法之后,我们便可以安全的监听WebMessageReceived事件,在CoreWebView2_WebMessageReceived事件处理函数中,出于安全起见,我们试图以TryGetWebMessageAsString的方法以字符串的格式接收消息内容,并且以系统弹窗MessageBox的方式进行展示,这里只是我们临时的一种方案,用于演示哈。
asyncvoidInitializeAsync(){//确保WebView对象已经初始化完成awaitWebViewForMain.EnsureCoreWebView2Async(null);//监听来自WebView的消息WebViewForMain.CoreWebView2.WebMessageReceived+=CoreWebView2_WebMessageReceived;//模拟WebView的网站发送消息awaitWebViewForMain.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.postMessage(window.document.URL);");}有了前面步骤中对WebView2实例的CoreWebView2对象针对WebMessageReceived事件的监听处理之后,我们可能需要模拟一下WebView网站内对客户端的消息动作,以便验证我们的监听处理是否符合预期,通过CoreWebView2对象的AddScriptToExecuteOnDocumentCreatedAsync方法,我们可以在新的网页内容被创建完成后追加一个PostMessage的动作,把当前网页的地址发送给客户端。
asyncvoidInitializeAsync(){//确保WebView对象已经初始化完成awaitWebViewForMain.EnsureCoreWebView2Async(null);//模拟WebView的网站监听消息awaitWebViewForMain.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.addEventListener(\'message\',event=>alert(event.data));");}前面我们模拟了从WebView网站发送消息,那么反过来,我们也需要模拟下网站监听来自客户端的消息,以便后续响应我们从客户端发送消息给网站。
通过CoreWebView2对象的AddScriptToExecuteOnDocumentCreatedAsync方法,我们可以在新的网页内容被创建完成后追加一个AddEventListener的动作,监听来自客户端的消息,并且以警告弹窗的形式把消息内容展示出来。
具体效果,稍后将进行验证。
a.新增消息发送面板
b.响应定制化消息发送
privatevoidBorderForPost_MouseDown(objectsender,MouseButtonEventArgse){varmessageContext=TextBoxForMessage.Text.Trim();WebViewForMain.CoreWebView2.PostWebMessageAsString(messageContext);}在"发送按钮(TextBlockForPost)"的响应事件BorderForPost_MouseDown中,通过CoreWebView2对象的PostWebMessageAsString方法,我们可以将界面上的定制化消息发送到网站,如果网站能接收到的话,那么根据前面的监听机制,会弹出包含消息内容的警示弹窗,根据我们的设计,稍作注意是,需要重新加载新网页才能响应。
为了更方便的实现JS和本机之间的通信,我们还可以把本地方法通过AddHostObjectToScript方法暴漏给Web来实现调用,这等同于传统WebBrower控件的ObjectForScripting方法实现。
a.对WebView2进行一些安全设置,允许使用注入本机方法
等待CoreWebView2核心初始化完毕之后,我们应该尽快完成一些安全设置,允许使用注入本机方法。
privateasyncvoidDemo5Window_Loaded(objectsender,RoutedEventArgse){awaitWebViewForMain.EnsureCoreWebView2Async();WebViewForMain.CoreWebView2.Settings.AreHostObjectsAllowed=true;WebViewForMain.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled=true;WebViewForMain.CoreWebView2.Settings.IsScriptEnabled=true;WebViewForMain.CoreWebView2.Settings.IsWebMessageEnabled=true;}b.定义公开的本机方法类
#pragmawarningdisableCS0618[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDual)]#pragmawarningrestoreCS0618[System.Runtime.InteropServices.ComVisible(true)]publicclassC2WHostObject{publicvoidClientFunction(stringrequestInfo){Console.WriteLine(requestInfo);}publicstringClientValueBack(stringrequestInfo){returnrequestInfo;}}这里对需要公开的本机方法类,需要通过System.Runtime.InteropServices.ComVisible(true)和System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDual)来公开它,否则将不可见。
c.等待CoreWebView2核心初始化完毕之后,注册本机公开方法
privateasyncvoidDemo5Window_Loaded(objectsender,RoutedEventArgse){awaitWebViewForMain.EnsureCoreWebView2Async();WebViewForMain.CoreWebView2.AddHostObjectToScript("webView2Bridge",newC2WHostObject());}这里需要给这个公开方法对象取个名称,这里我们暂时叫它:webView2Bridge。
d.在WebView2中F12进入DevTool尝试调用
而要在WPF中引入字体,并且使用,我们先把下载好的字体丢进项目下Fonts目录。
记得将字体文件设置成"始终复制"和生成操作为"内容"。
稍后在TextBlock中写FontFamily使用/MiniEdge;component/Fonts/#SegoeFluentIcons,其中MiniEdge是程序集的命名空间,Fonts是字体文件的路径,而SegoeFluentIcons是字体名称。
字体名称建议你双击.ttf打开看一下。
而在TextBlock中的Text需要采用开头和;结尾的编码,比如:
b.响应后退、前进、刷新、停止、主页按钮动作
///
回到主页按钮,暂时用CoreWebView2对象的Navigate方法来实现,其实我理解点击主页之后,应要清空前后导航的,但是还没找到对应的方法来做这件事。
c.优化后退、前进、刷新、停止、主页按钮交互
privatevoidBorderForButton_MouseEnter(objectsender,MouseEventArgse){varborder=senderasBorder;if(border.IsEnabled){border.Background=newSolidColorBrush(Colors.White);border.Focus();}}privatevoidBorderForButton_MouseLeave(objectsender,MouseEventArgse){varborder=senderasBorder;if(border.IsEnabled){border.Background=newSolidColorBrush(Colors.Transparent);}}实际上,我们给所有的图标按钮标配了一个效果,就是鼠标移上去就背景变白,移开后恢复,这样交互更加明确。
对于刷新和停止按钮,我们还需要根据是否正在加载来切换他们的显影,那么在之前的IsNavigationProgress中处理就好了。
d.优化导航按钮为图标按钮,统一交互和视觉
e.优化地址输入框交互和视觉体验
privatevoidTextBoxForNaviAddress_MouseEnter(objectsender,MouseEventArgse){BorderForNaviAddress.BorderBrush=newSolidColorBrush(Color.FromRgb(143,177,229));BorderForNaviAddress.BorderThickness=newThickness(1.5);}privatevoidTextBoxForNaviAddress_MouseLeave(objectsender,MouseEventArgse){BorderForNaviAddress.BorderBrush=newSolidColorBrush(Colors.Gray);BorderForNaviAddress.BorderThickness=newThickness(1);}接下来,当然输入框被鼠标靠近的时候,我们让输入框背后的背景边框变个颜色,并且加粗边框,被鼠标移开的时候,效果还原。
f.优化地址输入框直达和搜索体验
有时候用户可能输入的是一个网址链接,或者是一个不带HTTP头的链接,亦或只是联想的一些关键词,那么我们分开处理,以确保得到最佳体验。
g.不如取个更好的名字吧
之前我们管它叫WebView2浏览器,该给它取个正式的名称了,不如就叫MiniEdge吧,毕竟是借鉴了Edge的交互和视觉,还复用了它的渲染引擎。
需要注意的是,我们同时也把程序集名称一起改了。
这样最终exe就会改名字了。
注意也要把Demo4Window.xaml的Title改了。
每个开发团队在构建其应用程序时都遵循不同的做法。生成WebView2生产应用时,建议遵循这些建议和最佳做法。
我们通常建议使用"EvergreenWebView2运行时"。固定版本运行时分发仅建议用于具有严格兼容性要求的应用。"Evergreen运行时"在客户端上自动更新,以便你的WebView2应用可以使用最新的功能和安全修补程序。与固定版本运行时相比,"Evergreen运行时"还需要更少的磁盘上的存储空间。
如果使用"Evergreen运行时",在运行WebView2应用之前,测试是否已在客户端上安装"EvergreenWebView2运行时"。
使用"EvergreenWebView2运行时"时,运行时会自动更新,因此必须定期运行兼容性测试。若要确保WebView2应用继续正常工作,请针对MicrosoftEdgeInsider(preview)Channels(Beta、Dev或Canary)在WebView2控件中测试Web内容。
本指南类似于我们向Web开发人员提供的指导。
若要运行使用Webview2SDK的特定版本开发的WebView2应用,客户端必须已安装WebView2运行时的兼容版本。由于API不断添加到WebView2,因此也发布了新版本的运行时以支持新的API。使用功能检测确保安装在客户端上的WebView2运行时支持WebView2应用使用的较新的API。
如果使用"EvergreenWebView2运行时",在某些情况下,客户端上的运行时尚未自动更新到最新版本。例如,如果客户端没有Internet访问权限,则运行时不会自动更新。此外,某些组策略会暂停运行时的更新。将更新推送到WebView2应用时,如果应用尝试调用客户端安装运行时中不可用的较新API,该应用可能无法运行。
若要解决此问题,在代码调用最近添加的WebView2API之前,测试该API在客户端的安装运行时中是否可用。此较新功能测试与其他Web开发最佳实践类似,这些最佳实践在使用新的WebAPI之前检测支持的功能。若要测试已安装运行时中的API可用性,请使用:
如果使用固定版本的"WebView2运行时",请确保定期更新与应用打包的"WebView2运行时",以减少安全风险。在Webview2应用中使用第三方内容时,始终考虑不受信任的内容。
将新版本的"EvergreenWebView2运行时"下载到客户端后,正在运行的任何WebView2应用将继续使用早期版本的运行时,直到发布浏览器进程。此行为允许应用连续运行,并阻止删除以前的运行时。若要使用新版本的运行时,需要释放对以前的WebView2环境对象的所有引用,或重新启动应用。下次应用创建新的WebView2环境时,应用将使用新版本的运行时。
当新版本的运行时可用时,你的应用可以自动采取措施,例如通知用户重新启动该应用。若要检测新版本的运行时是否可用,可以在代码中使用add_NewBrowserVersionAvailable(Win32)或CoreWebView2Environment.NewBrowserVersionAvailable(.NET)事件。如果你的代码处理重新启动应用,请考虑在WebView2应用退出之前保存用户状态。
WebView2应用创建用户数据文件夹来存储Cookie、凭据和权限等数据。创建文件夹后,应用负责管理用户数据文件夹的生命周期。例如,卸载应用时,你的应用必须执行清理操作。
WebView2应用应侦听和处理事件,以便该应用可以从支持WebView2应用进程的运行时进程故障ProcessFailed中恢复。
与应用进程一起运行的运行时进程集合支持WebView2应用。这些支持运行时进程可能由于各种原因(如内存不足或用户终止)而失败。当支持运行时进程失败时,WebView2将通过引发ProcessFailed事件通知应用。
对于任何WebView2应用,请确保遵循我们建议的WebView2安全性最佳做法。
WebView2控件允许开发人员在本机应用程序中承载Web内容。正确使用时,承载Web内容具有多项优势,例如使用基于Web的UI、访问Web平台的功能、跨平台共享代码等。
为了避免承载Web内容时可能出现的漏洞,请确保设计WebView2应用程序以密切监视Web内容和主机应用程序之间的交互: