BrowserView

该文档描述了如何在 WinForms,WPF 和 Avalonia UI 应用程序中嵌入一个显示网页内容的可视化组件。

嵌入

DotNetBrowser 可用于使用以下 .NET GUI 框架构建的 .NET 应用程序:

  • WinForms
  • WPF
  • Avalonia UI

IBrowser 组件本身并不是一个可用于显示网页的可视化组件。 要显示 IBrowser中加载的网页内容,请根据所使用的 GUI 框架,使用以下控件之一:

  • DotNetBrowser.WinForms.BrowserView
  • DotNetBrowser.Wpf.BrowserView
  • DotNetBrowser.AvaloniaUi.BrowserView

所有这些控件都实现了 IBrowserView 接口。 必要时通过调用 InitializeFrom(IBrowser) 扩展方法建立视图与特定 IBrowser 实例的连接。

从单个浏览器初始化多个视图是不可能的 - 如果一个浏览器视图绑定到该浏览器实例,则该视图将被后续的 InitializeFrom 调用取消初始化。

InitializeFrom(IBrowser) 扩展方法应从 UI 线程调用。

当应用程序关闭时,IBrowserView 实现不会处理已连接的 IBrowserIEngine 实例。 因此,即使关闭了所有应用程序窗口,浏览器和引擎也会继续运行,并阻止应用程序终止。 要解决这种情况,有必要在应用程序关闭时处理 IBrowserIEngine 实例。

WinForms

要在 .NET WinForms 应用程序中显示网页内容,请创建DotNetBrowser.WinForms.BrowserView 实例:

using DotNetBrowser.WinForms;
// ...
BrowserView browserView = new BrowserView();
browserView.InitializeFrom(browser);
Imports DotNetBrowser.WinForms
' ...
Dim browserView As New BrowserView()
browserView.InitializeFrom(browser)

并将其嵌入 Form中:

form.Controls.Add(view);
form.Controls.Add(view)

下面是完整的示例:

using System.Windows.Forms;
using DotNetBrowser.Browser;
using DotNetBrowser.Engine;
using DotNetBrowser.WinForms;

namespace Embedding.WinForms
{
    /// <summary>
    ///     本例演示如何将 DotNetBrowser
    ///     嵌入到 Windows Forms 应用程序中。
    /// </summary>
    public partial class Form1 : Form
    {
        private const string Url = "https://html5test.teamdev.com/";
        private readonly IBrowser browser;
        private readonly IEngine engine;

        public Form1()
        {
            // 创建 Windows Forms BrowserView 控件。
            BrowserView browserView = new BrowserView
            {
                Dock = DockStyle.Fill
            };

            // 创建并初始化 IEngine 实例。
            EngineOptions engineOptions = new EngineOptions.Builder
            {
                RenderingMode = RenderingMode.HardwareAccelerated
            }.Build();
            engine = EngineFactory.Create(engineOptions);

            // 创建 IBrowser 实例。
            browser = engine.CreateBrowser();

            InitializeComponent();
            
            // 将 BrowserView 控件添加到 Form。
            Controls.Add(browserView);
            FormClosed += Form1_FormClosed;

            // 初始化 Windows Forms BrowserView 控件。
            browserView.InitializeFrom(browser);
            browser.Navigation.LoadUrl(Url);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            browser?.Dispose();
            engine?.Dispose();
        }
    }
}
Imports System.Windows.Forms
Imports DotNetBrowser.Browser
Imports DotNetBrowser.Engine
Imports DotNetBrowser.WinForms

Namespace Embedding.WinForms
    ''' <summary>
    '''     此示例演示如何将 DotNetBrowser 嵌入
    '''     到 Windows Forms 应用程序中。
    ''' </summary>
    Partial Public Class Form1
        Inherits Form

        Private Const Url As String = "https://html5test.teamdev.com/"
        Private ReadOnly browser As IBrowser
        Private ReadOnly engine As IEngine

        Public Sub New()
            ' 创建 Windows Forms BrowserView 控件。
            Dim browserView As New BrowserView With {.Dock = DockStyle.Fill}

            ' 创建和初始化 IEngine 实例。
            Dim engineOptions As EngineOptions = New EngineOptions.Builder With {
                .RenderingMode = RenderingMode.HardwareAccelerated
            }.Build()
            engine = EngineFactory.Create(engineOptions)

            ' 创建 IBrowser 实例。
            browser = engine.CreateBrowser()

            InitializeComponent()

            ' 将 BrowserView 控件添加到 Form 中。
            Controls.Add(browserView)
            AddHandler FormClosed, AddressOf Form1_FormClosed

            ' 初始化 Windows Forms BrowserView 控件。
            browserView.InitializeFrom(browser)
            browser.Navigation.LoadUrl(Url)
        End Sub

        Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs)
            browser?.Dispose()
            engine?.Dispose()
        End Sub
    End Class
End Namespace

该示例的输出如下所示: WinForms View

我们的存储库中提供了完整的项目: C#, VB.

WPF

要在 WPF 应用程序中显示网页内容,请创建一个 DotNetBrowser.Wpf.BrowserView 实例:

using DotNetBrowser.Wpf;
// ...
BrowserView browserView = new BrowserView();
browserView.InitializeFrom(browser);
Imports DotNetBrowser.Wpf
' ...
Dim browserView As New BrowserView()
browserView.InitializeFrom(browser)

下面是完整的示例:

MainWindow.xaml

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:WPF="clr-namespace:DotNetBrowser.Wpf;assembly=DotNetBrowser.Wpf"
    x:Class="Embedding.Wpf.MainWindow"
    mc:Ignorable="d"
    Title="MainWindow" Height="480" Width="800" Closed="Window_Closed">
    <Grid>
        <WPF:BrowserView Name="browserView" />
    </Grid>
</Window>

MainWindow.xaml.cs

MainWindow.xaml.vb

using System;
using System.Windows;
using DotNetBrowser.Browser;
using DotNetBrowser.Engine;

namespace Embedding.Wpf
{
    /// <summary>
    ///     此示例演示如何将 DotNetBrowser 嵌入
    ///     到 WPF 应用程序中。
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string Url = "https://html5test.teamdev.com/";
        private readonly IBrowser browser;
        private readonly IEngine engine;

        public MainWindow()
        {
            // 创建和初始化 IEngine 实例。
            EngineOptions engineOptions = new EngineOptions.Builder
            {
                RenderingMode = RenderingMode.HardwareAccelerated
            }.Build();
            engine = EngineFactory.Create(engineOptions);

            // 创建 IBrowser 实例。
            browser = engine.CreateBrowser();

            InitializeComponent();

            // 初始化 WPF BrowserView 控件。
            browserView.InitializeFrom(browser);
            browser.Navigation.LoadUrl(Url);
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            browser?.Dispose();
            engine?.Dispose();
        }
    }
}
Imports System.Windows
Imports DotNetBrowser.Browser
Imports DotNetBrowser.Engine

Namespace Embedding.Wpf
    ''' <summary>
    '''     此示例演示如何将 DotNetBrowser 嵌入
    '''     到 WPF 应用程序中。
    ''' </summary>
    Partial Public Class MainWindow
        Inherits Window

        Private Const Url As String = "https://html5test.teamdev.com/"
        Private ReadOnly browser As IBrowser
        Private ReadOnly engine As IEngine

        Public Sub New()
            ' 创建和初始化 IEngine 实例。
            Dim engineOptions As EngineOptions = New EngineOptions.Builder With {
                .RenderingMode = RenderingMode.HardwareAccelerated
            }.Build()
            engine = EngineFactory.Create(engineOptions)

            ' 创建 IBrowser 实例。
            browser = engine.CreateBrowser()

            InitializeComponent()

            ' 初始化 WPF BrowserView 控件。
            browserView.InitializeFrom(browser)
            browser.Navigation.LoadUrl(Url)
        End Sub

        Private Sub Window_Closed(sender As Object, e As EventArgs)
            browser?.Dispose()
            engine?.Dispose()
        End Sub
    End Class
End Namespace

该示例的输出如下所示: WPF View

完整的项目在我们的存储库中可用: C#, VB.

ElementHost

我们建议在 WinForms 应用程序中使用 WinForms BrowserView ,在 WPF 应用程序中使用 WPF BrowserView

有时您需要将 WPF BrowserView 嵌入到 WinForms 应用程序中。 例如,当使用 WPF UI 工具包开发复杂的网页浏览器控件时,您必须在 WinForms 应用程序中显示此 WPF 控件。 例如,当使用 WPF UI 工具包开发复杂的网页浏览器控件时,您必须在 WinForms 应用程序中显示此 WPF 控件。

从 v.2.0 开始,您可以使用 ElementHost 将 WPF BrowserView 嵌入到 WinForms 窗口中。 它支持所有的渲染模式。 它支持所有的渲染模式。

using System;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
using DotNetBrowser.Browser;
using DotNetBrowser.Engine;
using DotNetBrowser.Wpf;

namespace ElementHostEmbedding.WinForms
{
    public partial class Form1 : Form
    {
        private const string Url = "https://html5test.teamdev.com";
        private readonly IBrowser browser;
        private readonly IEngine engine;
        private readonly ElementHost host;

        public Form1()
        {
            // 创建和初始化 IEngine 实例。
            EngineOptions engineOptions = new EngineOptions.Builder
            {
                RenderingMode = RenderingMode.OffScreen,
                // 以编程方式设置许可证密钥。
                LicenseKey = "your_license_key_goes_here"
            }.Build();
            engine = EngineFactory.Create(engineOptions);

            // 创建 IBrowser 实例。
            browser = engine.CreateBrowser();
            // 创建  WPF BrowserView 控件。
            BrowserView browserView = new BrowserView();
            
            InitializeComponent();
            FormClosed += Form1_FormClosed;

            // 创建和初始化 ElementHost 控件。
            host = new ElementHost
            {
                Dock = DockStyle.Fill,
                Child = browserView
            };
            Controls.Add(host);

            // 初始化 WPF BrowserView 控件。
            browserView.InitializeFrom(browser);
            browser.Navigation.LoadUrl(Url);
        }

        private void Form1_FormClosed(object sender, EventArgs e)
        {
            browser?.Dispose();
            engine?.Dispose();
        }
    }
}
Imports System.Windows.Forms.Integration
Imports DotNetBrowser.Browser
Imports DotNetBrowser.Engine
Imports DotNetBrowser.Wpf

Namespace ElementHostEmbedding.WinForms
    Partial Public Class Form1
        Inherits Form

        Private Const Url As String = "https://html5test.teamdev.com"
        Private ReadOnly browser As IBrowser
        Private ReadOnly engine As IEngine
        Private ReadOnly host As ElementHost

        Public Sub New()
            ' 创建和初始化 IEngine 实例。
            Dim engineOptions As EngineOptions = New EngineOptions.Builder With {
                .RenderingMode = RenderingMode.OffScreen,
                .LicenseKey = "your_license_key_goes_here"
            }.Build()
            engine = EngineFactory.Create(engineOptions)

            ' 创建 IBrowser 实例。
            browser = engine.CreateBrowser()
            ' 创建  WPF BrowserView 控件。
            Dim browserView As New BrowserView()

            InitializeComponent()
            AddHandler FormClosed, AddressOf Form1_FormClosed

            ' 创建和初始化 ElementHost 控件。
            host = New ElementHost With {
                .Dock = DockStyle.Fill,
                .Child = browserView
            }
            Controls.Add(host)

            ' 初始化 WPF BrowserView 控件。
            browserView.InitializeFrom(browser)
            browser.Navigation.LoadUrl(Url)
        End Sub

        Private Sub Form1_FormClosed(sender As Object, e As EventArgs)
            browser?.Dispose()
            engine?.Dispose()
        End Sub
    End Class
End Namespace

完整的示例可以在我们的存储库中找到: C#, VB.

Avalonia UI

要在 Avalonia UI 应用程序中显示网页内容,请创建一个 DotNetBrowser.AvaloniaUi.BrowserView 实例:

using DotNetBrowser.AvaloniaUi;
// ...
BrowserView browserView = new BrowserView();
browserView.InitializeFrom(browser);
Imports DotNetBrowser.AvaloniaUi
' ...
Dim browserView As New BrowserView()
browserView.InitializeFrom(browser)

下面是完整的示例:

MainWindow.axaml

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:app="clr-namespace:DotNetBrowser.AvaloniaUi;assembly=DotNetBrowser.AvaloniaUi"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="Embedding.AvaloniaUi.MainWindow"
        Title="Embedding.AvaloniaUi" Closed="Window_Closed">
    <app:BrowserView x:Name="BrowserView"/>
</Window>

MainWindow.axaml.cs

using System;
using Avalonia.Controls;
using DotNetBrowser.Browser;
using DotNetBrowser.Engine;

namespace Embedding.AvaloniaUi
{

    /// <summary>
    ///     此示例演示了如何将 DotNetBrowser 嵌入
    ///     到 Avalonia 应用程序中。
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string Url = "https://html5test.teamdev.com/";
        private readonly IBrowser browser;
        private readonly IEngine engine;

        public MainWindow()
        {
            // 创建并初始化 IEngine 实例。
            EngineOptions engineOptions = new EngineOptions.Builder
            {
                //LicenseKey = "your_license_key"
            }.Build();
            engine = EngineFactory.Create(engineOptions);

            // 创建 IBrowser 实例。
            browser = engine.CreateBrowser();

            InitializeComponent();

            // 初始化 Avalonia UI 的 BrowserView 控件。
            BrowserView.InitializeFrom(browser);
            browser.Navigation.LoadUrl(Url);
        }

        private void Window_Closed(object? sender, EventArgs e)
        {
            browser?.Dispose();
            engine?.Dispose();
        }
    }
}

该示例的输出如下所示: Avalonia UI View

完整的项目可在我们的存储库中找到: C#, VB

渲染

DotNetBrowser 支持多种渲染模式。 在本节中,我们将介绍每种模式的性能和局限性,并根据 .NET 应用程序的类型为您提供选择正确模式的建议。

硬件加速

该库使用 Chromium GPU 进程中的 GPU 渲染网页内容,并将其直接显示在表面上。 在这种模式下, BrowserView 会创建并嵌入一个本地重量级窗口(表面),库在该窗口上渲染生成的像素。

离屏

该库使用 Chromium GPU 进程中的 GPU 渲染网页内容,并将像素复制到 .NET 进程内存中分配的离屏缓冲区。 在这种模式下, BrowserView 会创建并嵌入一个轻量级组件,该组件从离屏缓冲区读取像素并使用 UI 框架功能显示它们。

局限性

WPF 空域问题

当启用 HardwareAccelerated 渲染模式时,不建议在 BrowserView 上显示其他 WPF 组件,因为 BrowserView 使用 HwndHost 显示本机 Win32 窗口。 因此,它通常会导致众所周知的空域问题

WPF 分层窗口

使用 AllowsTransparency 样式配置 WPF Window 会将 WS_EX_LAYERED 窗口样式标志添加到 Windows 上的 WPF 窗口。 此标志用于创建分层窗口。 分层窗口是一种在屏幕外绘制内容的窗口。 如果我们在启用 HardwareAccelerated 渲染模式时将本机窗口嵌入到分层窗口中,那么由于窗口类型冲突,其内容则不会被绘制。

鼠标、键盘、触摸、拖放

OffScreen 渲染模式下,鼠标、键盘和触摸事件在 .NET 端处理并转发给 Chromium 引擎。

目前,在 WPF 和 Avalonia UI 中都提供全触摸和手势支持。 在 WinForms 中,这种功能仅限于轻敲和长按,因为 WinForms 本身对触摸的支持有限。

OffScreen 渲染模式下,WPF、WinForms 和 Avalonia UI 均不支持拖放(DnD)功能。

Go Top