我需要使用某些库中的PdfViewer。该库为Android,IOS,UWP平台提供控件,但不为WPF平台提供控件。如何仅为WPF平台创建渲染器?
WPF渲染器:
[assembly: ExportRenderer(typeof(PdfViewer), typeof(PdfViewerRenderer))]
public class PdfViewerRenderer : Xamarin.Forms.Platform.WPF.ViewRenderer<PdfViewer, WPF.PlatformImplementations.PdfViewer>{}
WPF控件的实现:
namespace WPF.PlatformImplementations
{ public class PdfViewer : PdfViewerControl { } }
Net标准库包含PdfViewer,它是从SfPdfViewer的库中派生的:
namespace Views
{ public class PdfViewer : SfPdfViewer { } }
以上方法不适用于WPF,不适用于其他平台。当我将继承从SfPdfViewer更改为Xamarin.Forms.View时,它适用于WPF,但显然不适用于其他平台。
答案 0 :(得分:3)
每个Xamarin.Forms
控件都有一个随附的渲染器,用于每个需要创建本机控件实例的平台。
SfPdfViewer
是一个xamarin形式的控件,仅表示共享的UI状态和交互逻辑。它需要一个相应的本机控件来实际呈现视图并与WPF
平台进行交互。
为此,第一步是选择一个基于WPF
的控件来查看PDF文件。在此示例中,我使用了WPF Pdf Viewer by SyncFusion;但任何其他选项-可能像嵌入式WebView或开源选项如PdfiumViewer也应起作用。
在WPF项目中为Syncfusion.PdfViewer.WPF安装nuget程序包
使用平台渲染器,将带有表单元素(SfPdfViewer
)与本机控件(PdfViewerControl
)相连。
[assembly: ExportRenderer(typeof(SfPdfViewer), typeof(SfPdfViewerRenderer))]
namespace PdfViewer.Demo.WPF
{
public class SfPdfViewerRenderer
: ViewRenderer<SfPdfViewer, Syncfusion.Windows.PdfViewer.PdfViewerControl>
{
Syncfusion.Windows.PdfViewer.PdfViewerControl _nativeControl;
protected override void OnElementChanged(ElementChangedEventArgs<SfPdfViewer> e)
{
base.OnElementChanged(e);
// If new forms element attached, wire up the native control
if (e.NewElement != null)
{
_nativeControl = new Syncfusion.Windows.PdfViewer.PdfViewerControl();
SetNativeControl(_nativeControl);
}
// Otherwise perform some cleanup
else
{
if(_nativeControl != null)
{
_nativeControl.Unload();
_nativeControl = null;
}
}
UpdateNativeControlProperties();
}
/// <summary>
/// Basically sync property values from forms-element (SfPdfViewer)
/// to native-control (PdfViewerControl)
/// In this example - we only sync with 'input file stream'
/// </summary>
private void UpdateNativeControlProperties()
{
if (Element != null && Element.InputFileStream != null)
{
Control.Load(Element.InputFileStream);
}
else
{
Control.Unload();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(SfPdfViewer.InputFileStream))
{
UpdateNativeControlProperties();
}
}
}
}
答案 1 :(得分:0)
一种实现方法是在Core项目中创建一个CustomPdfViewer
接口,并使用依赖注入在每个本机项目中具有单独的实现。
在每个iOS,Android和UWP项目的本机实现中,只需使其使用适用于您的PdfViewer
库即可。
然后对于WPF,只需使用SfPdfViewer
。
例如:您可以通过示例查看DependencyService上的official documentation here
执行此操作后,您将拥有解决方案。但是,如果您想更进一步并访问在XAML中创建的CustomPdfViewer
,则可以使用由术语local
表示的“ XAML Markup Extensions”,如示例中所示here。