如何使用Xamarin.Forms、WPF和Syncfusion控件在屏幕上呈现PDF?

如何使用Xamarin.Forms、WPF和Syncfusion控件在屏幕上呈现PDF?,wpf,pdf,xamarin,xamarin.forms,syncfusion,Wpf,Pdf,Xamarin,Xamarin.forms,Syncfusion,我正在编写一个针对WPF和MacOS的Xamarin.Forms应用程序。在shared Xamarin.Forms项目中,我有一个基本的自定义控件,该控件具有源文件等属性,保存表示从web服务或文件系统收集的PDF的流。在特定于平台的项目中,我有定制的渲染器,可以根据特定于平台的需要渲染PDF文件 对于MacOS来说,这个问题很容易解决。然而,过了一段时间,我发现WPF工具包没有为PDF提供本机控件。经过一些研究,我选择了使用 我不需要什么特别的东西,只需要能够在屏幕上显示PDF文件,而不需要

我正在编写一个针对WPF和MacOS的Xamarin.Forms应用程序。在shared Xamarin.Forms项目中,我有一个基本的自定义控件,该控件具有
源文件
等属性,保存表示从web服务或文件系统收集的PDF的流。在特定于平台的项目中,我有定制的渲染器,可以根据特定于平台的需要渲染PDF文件

对于MacOS来说,这个问题很容易解决。然而,过了一段时间,我发现WPF工具包没有为PDF提供本机控件。经过一些研究,我选择了使用

我不需要什么特别的东西,只需要能够在屏幕上显示PDF文件,而不需要工具栏或边栏,因此,我选择使用
PdfDocumentView
加载PDF文件

但是,当使用
PdfViwerControl
PdfDocumentView
时,我似乎无法一次加载两个以上的页面。这些控件的垂直滚动条从不显示,但水平滚动条工作正常

以下是我迄今为止的代码(加载本地硬编码本地文件以进行测试):

查看

<?xml version="1.0" encoding="UTF-8" ?>
<Grid
    x:Class="MyApp.Views.DocumentOverview"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="MyApp.Controls">

    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Grid Grid.Row="0">
        
    </Grid>

    <Grid Grid.Row="1" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <controls:CustomPdfViewer x:Name="myPdfViewer"
                BackgroundColor="Transparent"
                HorizontalOptions="FillAndExpand"
                VerticalOptions="FillAndExpand" />
    </Grid>
</Grid>
自定义渲染器

[assembly: ExportRenderer(typeof(CustomPdfViewer), typeof(PdfLoaderRenderer))]
namespace MyApp.WPF.CustomRenderers
{
    class PdfLoaderRenderer : ViewRenderer<CustomPdfViewer, PdfDocumentView>
    {
        PdfDocumentView _pdfDocument = new PdfDocumentView();

        protected override void OnElementChanged(ElementChangedEventArgs<CustomPdfViewer> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                SetNativeControl(_pdfDocument);
            }
        }

        protected async override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName.Equals(nameof(Element.Source)))
            {
                await LoadFile();
            }

            base.OnElementPropertyChanged(sender, e);
        }

        private async Task LoadFile()
        {
            if (Element != null && Element.Source != null)
            {
                _pdfDocument.Load(@"C:\Sources\Document.pdf");
            }
        }
    }
}
[程序集:ExportRenderer(typeof(CustomPdfViewer)、typeof(PdfLoaderRenderer))]
命名空间MyApp.WPF.CustomRenders
{
类PdfLoaderRenderer:ViewRenderer
{
PdfDocumentView_pdfDocument=新的PdfDocumentView();
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(例如NewElement!=null)
{
SetNativeControl(_PDF文档);
}
}
受保护的异步重写void OnElementPropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
如果(e.PropertyName.Equals(nameof(Element.Source)))
{
等待加载文件();
}
base.OnElementPropertyChanged(发送方,e);
}
专用异步任务加载文件()
{
if(Element!=null&&Element.Source!=null)
{
_Load(@“C:\Sources\Document.pdf”);
}
}
}
}
当我将控件放入
滚动视图
中并强制
高度请求
达到3000或4000左右时,我可以看到第二页。但不管怎样,即使通过强制设置高度为其他页面留出了空间,它们也不会被渲染。我认为这是因为Syncfusion控件的虚拟化功能,以提高性能:


但在这种情况下,这可能会影响我使用控件的方式。如何正确使用Syncfusion PDF Viewer for WPF来呈现屏幕上有多个页面的PDF?现在使用WebView不是一个很好的选择,对于第三方控件,我只能访问Syncfusion控件。

请参考以下论坛,其中针对您的需求处理了相同的场景,并检查这些信息是否有助于您解决问题

注意:我为Syncfusion工作

[assembly: ExportRenderer(typeof(CustomPdfViewer), typeof(PdfLoaderRenderer))]
namespace MyApp.WPF.CustomRenderers
{
    class PdfLoaderRenderer : ViewRenderer<CustomPdfViewer, PdfDocumentView>
    {
        PdfDocumentView _pdfDocument = new PdfDocumentView();

        protected override void OnElementChanged(ElementChangedEventArgs<CustomPdfViewer> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                SetNativeControl(_pdfDocument);
            }
        }

        protected async override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName.Equals(nameof(Element.Source)))
            {
                await LoadFile();
            }

            base.OnElementPropertyChanged(sender, e);
        }

        private async Task LoadFile()
        {
            if (Element != null && Element.Source != null)
            {
                _pdfDocument.Load(@"C:\Sources\Document.pdf");
            }
        }
    }
}