首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为单一平台创建缺少的自定义渲染器

为单一平台创建缺少的自定义渲染器
EN

Stack Overflow用户
提问于 2019-11-28 18:36:55
回答 2查看 312关注 0票数 3

我需要使用某个库中的PdfViewer。此库提供Android、IOS、UWP平台的控件,但不提供WPF平台的控件。如何创建一个只为WPF平台的渲染器?

WPF渲染器:

代码语言:javascript
运行
复制
[assembly: ExportRenderer(typeof(PdfViewer), typeof(PdfViewerRenderer))]
public class PdfViewerRenderer : Xamarin.Forms.Platform.WPF.ViewRenderer<PdfViewer, WPF.PlatformImplementations.PdfViewer>
{

}

WPF控件实现:

代码语言:javascript
运行
复制
namespace WPF.PlatformImplementations
{ 
    public class PdfViewer 
    { 
     //custom implementation of pdf viewer for wpf
    } 
}

Net标准库包含从库中的SfPdfViewer派生的PdfViewer:

代码语言:javascript
运行
复制
namespace Views
{ 
    public class PdfViewer : SfPdfViewer 
    { 
     //implementation of pdf viewer using base class from multiplatform library
    } 
}

上述方法不适用于WPF,但适用于其他平台。当我将继承从SfPdfViewer更改为Xamarin.Forms.View时,它对WPF有效,但显然不适用于其他平台。因此,问题是如何使渲染器机制基于Xamarin.Forms.View将Views.PdfViewer识别为控件。

EN

回答 2

Stack Overflow用户

发布于 2020-04-12 00:34:58

对于需要创建本机控件实例的每个平台,每个Xamarin.Forms控件都有一个附带的渲染器。

SfPdfViewer是一个xamarin-forms控件,它只表示共享的UI状态和交互逻辑。它需要一个相应的本机控件来实际呈现视图并与WPF平台交互。

为了做到这一点,第一步是选择一个基于WPF的控件来查看PDF文件。在本例中,我使用了WPF Pdf Viewer by SyncFusion;但任何其他选项--可能像嵌入式WebView或像PdfiumViewer这样的开源选项--也应该可以使用。

步骤1:

在WPF项目中安装Syncfusion.PdfViewer.WPF的nuget包

第2步:

使用平台渲染器将表单元素(SfPdfViewer)与本机控件(PdfViewerControl)连接起来。

代码语言:javascript
运行
复制
[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();
            }
        }
    }
}

上传到Github上的参考示例项目。

票数 3
EN

Stack Overflow用户

发布于 2020-04-08 10:26:25

要做到这一点,一种方法是在核心项目中创建一个CustomPdfViewer接口,并在每个本机项目中使用依赖项注入进行单独的实现。

在每个iOS、Android和UWP项目的本机实现中,只需让它使用适合您的PdfViewer库即可。

然后对于WPF,只需使用SfPdfViewer即可。

你可以看看DependencyService上的official documentation here,里面有一些例子

一旦你这样做了,你就有了你的解决方案。但是,如果您想更进一步并访问在XAML中创建的CustomPdfViewer,则可以使用术语local表示的"XAML Markup Extensions“,在示例here中也可以看到。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59086846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档