基於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="&#xe678;" />
</Trigger>
<Trigger Property="ZoomLevelType" Value="Out">
    <Setter TargetName="PART_ZoomButton" Property="Content" Value="&#xe620;" />
</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="&#xe60c;" Style="{DynamicResource Button.FontButton}" Width="26" Height="26"/>
                <Button Content="&#xe699;" 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

項目邀請:如對該項目有興趣,歡迎聯系我共同開發!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM