一、網頁縮放分析
縮放入口
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
項目邀請:如對該項目有興趣,歡迎聯系我共同開發!!!