基於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, DependencyPropertyChangedEventArgs 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 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

 

四、源碼地址

gitee地址:https://gitee.com/sirius_machao/mweb-browser


免責聲明!

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



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