方法1:通过 NuGet 包安装并手动创建控件(推荐)

1. 安装 NuGet 包

1

2

3

<!-- 在你的 WPF 项目的 .csproj 文件中添加 -->

<PackageReference Include="PdfiumViewer" Version="2.11.0" />

<PackageReference Include="PdfiumViewer.Native.x86_64.v8-xfa" Version="2023.6.12.1" />

或通过 NuGet 包管理器控制台:

1

2

Install-Package PdfiumViewer

Install-Package PdfiumViewer.Native.x86_64.v8-xfa

2. 在 XAML 中设置 WindowsFormsHost

由于 PdfiumViewer 是 WinForms 控件,需要在 WPF 中使用 WindowsFormsHost

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<!-- 在 MainWindow.xaml 中 -->

<Window x:Class="YourNamespace.MainWindow"

        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:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

        mc:Ignorable="d"

        Title="PDF Viewer" Height="600" Width="800">

     

    <Grid>

        <WindowsFormsHost x:Name="pdfHost" Margin="10"/>

    </Grid>

</Window>

3. 在代码后台创建和使用 PdfViewer

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

using System;

using System.Windows;

using PdfiumViewer;

using System.Windows.Forms.Integration;

namespace YourNamespace

{

    public partial class MainWindow : Window

    {

        private PdfViewer pdfViewer;

         

        public MainWindow()

        {

            InitializeComponent();

            InitializePdfViewer();

        }

         

        private void InitializePdfViewer()

        {

            // 创建 PdfViewer 实例

            pdfViewer = new PdfViewer();

            pdfViewer.Dock = System.Windows.Forms.DockStyle.Fill;

             

            // 将 PdfViewer 添加到 WindowsFormsHost

            pdfHost.Child = pdfViewer;

        }

         

        // 打开 PDF 文件

        private void OpenPdf(string filePath)

        {

            try

            {

                // 加载 PDF 文档

                pdfViewer.Document = PdfDocument.Load(filePath);

            }

            catch (Exception ex)

            {

                MessageBox.Show($"打开 PDF 失败: {ex.Message}");

            }

        }

         

        // 示例:在窗口加载时打开 PDF

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            OpenPdf(@"C:\path\to\your\document.pdf");

        }

    }

}

方法2:创建自定义 WPF 控件(更优雅)

1. 创建 PdfViewerWrapper 用户控件

1

2

3

4

5

6

7

8

9

10

11

12

<!-- PdfViewerWrapper.xaml -->

<UserControl x:Class="YourNamespace.Controls.PdfViewerWrapper"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             mc:Ignorable="d"

             d:DesignHeight="450" d:DesignWidth="800">

    <Grid>

        <WindowsFormsHost x:Name="host"/>

    </Grid>

</UserControl>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

// PdfViewerWrapper.xaml.cs

using System;

using System.Windows;

using System.Windows.Controls;

using PdfiumViewer;

using System.Windows.Forms.Integration;

namespace YourNamespace.Controls

{

    public partial class PdfViewerWrapper : UserControl

    {

        private PdfViewer pdfViewer;

         

        public PdfViewerWrapper()

        {

            InitializeComponent();

            InitializePdfViewer();

        }

         

        private void InitializePdfViewer()

        {

            pdfViewer = new PdfViewer

            {

                Dock = System.Windows.Forms.DockStyle.Fill

            };

            host.Child = pdfViewer;

        }

         

        // 打开 PDF 文件

        public void LoadPdf(string filePath)

        {

            try

            {

                pdfViewer.Document = PdfDocument.Load(filePath);

            }

            catch (Exception ex)

            {

                MessageBox.Show($"加载 PDF 失败: {ex.Message}");

            }

        }

         

        // 从字节数组加载

        public void LoadPdf(byte[] pdfData)

        {

            try

            {

                pdfViewer.Document = PdfDocument.Load(pdfData);

            }

            catch (Exception ex)

            {

                MessageBox.Show($"加载 PDF 失败: {ex.Message}");

            }

        }

         

        // 从流加载

        public void LoadPdf(System.IO.Stream stream)

        {

            try

            {

                pdfViewer.Document = PdfDocument.Load(stream);

            }

            catch (Exception ex)

            {

                MessageBox.Show($"加载 PDF 失败: {ex.Message}");

            }

        }

         

        // 获取当前页面索引

        public int GetCurrentPage()

        {

            return pdfViewer?.Renderer?.Page ?? 0;

        }

         

        // 跳转到指定页面

        public void GoToPage(int page)

        {

            if (pdfViewer?.Renderer != null && page >= 0 && page < pdfViewer.Document.PageCount)

            {

                pdfViewer.Renderer.Page = page;

            }

        }

    }

}

2. 在主窗口中使用自定义控件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<!-- MainWindow.xaml -->

<Window x:Class="YourNamespace.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:controls="clr-namespace:YourNamespace.Controls"

        Title="PDF Viewer" Height="600" Width="800">

     

    <Grid>

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>

         

        <!-- 工具栏 -->

        <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10">

            <Button Content="打开 PDF" Click="OpenPdfButton_Click" Margin="5"/>

            <Button Content="上一页" Click="PrevPageButton_Click" Margin="5"/>

            <Button Content="下一页" Click="NextPageButton_Click" Margin="5"/>

            <TextBlock Text="页码:" VerticalAlignment="Center" Margin="10,0,5,0"/>

            <TextBlock x:Name="pageInfo" VerticalAlignment="Center"/>

        </StackPanel>

         

        <!-- PDF 查看器 -->

        <controls:PdfViewerWrapper x:Name="pdfViewerControl" Grid.Row="1"/>

    </Grid>

</Window>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

// MainWindow.xaml.cs

using Microsoft.Win32;

using System.Windows;

namespace YourNamespace

{

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

        }

         

        private void OpenPdfButton_Click(object sender, RoutedEventArgs e)

        {

            var openFileDialog = new OpenFileDialog

            {

                Filter = "PDF 文件|*.pdf|所有文件|*.*",

                Title = "选择 PDF 文件"

            };

             

            if (openFileDialog.ShowDialog() == true)

            {

                pdfViewerControl.LoadPdf(openFileDialog.FileName);

            }

        }

         

        private void PrevPageButton_Click(object sender, RoutedEventArgs e)

        {

            int currentPage = pdfViewerControl.GetCurrentPage();

            if (currentPage > 0)

            {

                pdfViewerControl.GoToPage(currentPage - 1);

            }

        }

         

        private void NextPageButton_Click(object sender, RoutedEventArgs e)

        {

            int currentPage = pdfViewerControl.GetCurrentPage();

            pdfViewerControl.GoToPage(currentPage + 1);

        }

    }

}

方法3:使用 PdfRenderer 而不是 PdfViewer

如果你只需要简单的 PDF 渲染(没有工具栏),可以使用 PdfRenderer

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

using System.Windows;

using System.Windows.Forms.Integration;

using PdfiumViewer;

public partial class MainWindow : Window

{

    private PdfRenderer pdfRenderer;

     

    public MainWindow()

    {

        InitializeComponent();

        InitializePdfRenderer();

    }

     

    private void InitializePdfRenderer()

    {

        pdfRenderer = new PdfRenderer();

        pdfRenderer.Dock = System.Windows.Forms.DockStyle.Fill;

        pdfRenderer.ZoomMode = PdfViewerZoomMode.FitWidth;

         

        // 添加到 WindowsFormsHost

        var host = new WindowsFormsHost();

        host.Child = pdfRenderer;

         

        // 添加到 WPF 容器

        contentContainer.Children.Add(host);

    }

     

    private void LoadPdf(string filePath)

    {

        var document = PdfDocument.Load(filePath);

        pdfRenderer.Load(document);

    }

}

解决常见问题

问题1:找不到 PdfiumViewer 控件

  • 原因:PdfiumViewer 是 WinForms 控件,不会自动出现在 WPF 工具箱中
  • 解决方案:手动创建控件实例,如上所示

问题2:运行时异常(DLL 未找到)

1

2

3

4

<!-- 在 .csproj 中确保包含 Native 包 -->

<PackageReference Include="PdfiumViewer.Native.x86_64.v8-xfa" Version="2023.6.12.1" />

<!-- 或 x86 版本 -->

<PackageReference Include="PdfiumViewer.Native.x86.v8-xfa" Version="2023.6.12.1" />

问题3:设计时看不到控件

  • 原因:WinForms 控件在 WPF 设计器中不可见
  • 解决方案:在设计时显示占位符,运行时加载真实控件

1

2

3

4

5

6

7

8

9

10

<!-- 在设计时显示标签,运行时替换 -->

<UserControl>

    <Grid>

        <TextBlock x:Name="designText"

                   Text="PDF Viewer (设计时)"

                   Visibility="{Binding IsInDesignMode, Converter={StaticResource BoolToVisibilityConverter}}"/>

        <WindowsFormsHost x:Name="host"

                          Visibility="{Binding IsInDesignMode, Converter={StaticResource BoolToVisibilityInverseConverter}}"/>

    </Grid>

</UserControl>

完整示例项目结构

1

2

3

4

5

6

7

8

9

YourSolution/

├── YourWpfProject/

│   ├── Controls/

│   │   ├── PdfViewerWrapper.xaml

│   │   └── PdfViewerWrapper.xaml.cs

│   ├── MainWindow.xaml

│   ├── MainWindow.xaml.cs

│   └── YourWpfProject.csproj

└── YourWpfProject.sln

在工具箱中手动添加控件(可选)

虽然不能直接拖拽,但你可以:

  1. 创建自定义控件库:将 PdfViewerWrapper 控件编译为独立的 DLL
  2. 添加到工具箱
    • 右键点击工具箱 → “选择项”
    • 浏览并选择你的控件 DLL
    • 控件将出现在工具箱中

总结

在 WPF 中使用 PdfiumViewer 的关键步骤:

  1. 安装 NuGet 包:PdfiumViewer 及其 Native 包
  2. 使用 WindowsFormsHost:承载 WinForms 控件
  3. 代码创建控件:在代码后台或自定义用户控件中实例化 PdfViewer
  4. 加载 PDF:使用 PdfDocument.Load() 方法

虽然不能像 WinForms 那样直接在工具箱中拖拽,但通过创建自定义用户控件,你可以在 WPF 中获得类似的开发体验。

更多推荐