一、網頁縮放分析
縮放入口
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++; } }
執行效果:
小彈窗按鈕命令繫結這裡不再贅述,詳情請檢視程式碼