BrowserView

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

嵌入

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

  • WinForms
  • WPF
  • Avalonia UI

IBrowser 组件本身不是允许显示网页的可视化组件。 要显示在 IBrowser 中加载的网页内容,请使用以下控件之一,具体取决于所使用的 GUI 框架:

  • DotNetBrowser.WinForms.BrowserView
  • DotNetBrowser.Wpf.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)

And embed it into a Form:

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

Here is the complete example:

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

namespace Embedding.WinForms
{
    /// <总结>
    ///     此示例演示如何将 DotNetBrowser 嵌入
    ///     到 Windows Forms 应用程序中。
    /// </总结>
    public partial class Form1 : Form
    {
        private const string Url = "https://html5test.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
    ''' <总结>
    '''     此示例演示如何将 DotNetBrowser 嵌入
    '''     到 Windows Forms 应用程序中。
    ''' </总结>
    Partial Public Class Form1
        Inherits Form

        Private Const Url As String = "https://html5test.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

The output of this example looks as follows: 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
{
    /// <总结>
    ///     此示例演示如何将 DotNetBrowser 嵌入
    ///     到 WPF 应用程序中。
    /// </总结>
    public partial class MainWindow : Window
    {
        private const string Url = "https://html5test.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
    ''' <总结>
    '''     此示例演示如何将 DotNetBrowser 嵌入
    '''     到 WPF 应用程序中。
    ''' </总结>
    Partial Public Class MainWindow
        Inherits Window

        Private Const Url As String = "https://html5test.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 控件。

从 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://teamdev.cn/dotnetbrowser";
        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://teamdev.cn/dotnetbrowser"
        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.

渲染

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 中支持完整的触摸和手势功能。 而在 WinForms 中,此功能仅限于点击和长按,因为 WinForms 本身对触摸的支持是有限的。

WPF 和 WinForm 均不支持拖放 (Drag and Drop) 功能。

Go Top