如何根据平台目标在自定义控件中使用不同的基础class?

How to use different base class in custom control depending on platform target?

我有一个用于 iOS 的自定义编辑器,但对于 UWP,我使用另一个名为 SfRichTextEditor.

的编辑器

现在我想知道如何创建一个可共享的 class,因为它们具有相同的可绑定属性,而不是做我目前所做的,即在它们之上创建一个 ContentView,这导致:

  1. 出于性能目的进行不必要的嵌套

  2. 重复代码

  3. 某些绑定似乎有问题(未验证,但有些奇怪)。

    <ContentView>
        <OnPlatform x:TypeArguments="View">
            <OnPlatform.Platforms>
                <On Platform="iOS">
    
                    <controls:CustomIOSEditor/>
                </On>
                <On Platform="UWP">
                    <controls:CustomUWPEditor/>
                </On>
            </OnPlatform.Platforms>
        </OnPlatform>
    </ContentView>
    

因此,如果可能的话,我希望有一个可共享的基础 class,而不是这种方法,以重用代码。

这些是我今天拥有的 x2 控件。

我的iOS自定义控件:

public class CustomIOSEditor : Editor // Using regular xamarin editor
{
    public static readonly BindableProperty StringResultCommandProperty =
        BindableProperty.Create(
            nameof(StringResultCommand),
            typeof(ICommand),
            typeof(CustomIOSEditor),
            default(ICommand));

    public object StringResultCommandParameter
    {
        get => GetValue(StringResultCommandParameterProperty);
        set => SetValue(StringResultCommandParameterProperty, value);
    }
}

我的 UWP 自定义控件:

public class CustomUWPEditor : SfRichTextEditor // Using SfRichTextEditor instead here.
{
    public static readonly BindableProperty StringResultCommandProperty =
        BindableProperty.Create(
            nameof(StringResultCommand),
            typeof(ICommand),
            typeof(CustomUWPEditor),
            default(ICommand));

    public object StringResultCommandParameter
    {
        get => GetValue(StringResultCommandParameterProperty);
        set => SetValue(StringResultCommandParameterProperty, value);
    }
}

最新线索** 更新** 共享.csproj:

苹果操作系统:

设置:

错误:

您要找的是SetNativeControl().

例如检查这个例子,

https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/view#creating-the-custom-renderer-on-uwp

在此处link粘贴上面的相同示例

注意 - 下面示例中的 CameraPreview 是 Xamarin.Form 元素,CaptureElement 是 UWP 控件

[assembly: ExportRenderer(typeof(CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.UWP
{
    public class CameraPreviewRenderer : ViewRenderer<CameraPreview, Windows.UI.Xaml.Controls.CaptureElement>
    {
        ...
        CaptureElement _captureElement;
        bool _isPreviewing;

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

            if (e.OldElement != null)
            {
                // Unsubscribe
                Tapped -= OnCameraPreviewTapped;
                ...
            }
            if (e.NewElement != null)
            {
                if (Control == null)
                {
                  ...
                  _captureElement = new CaptureElement();
                  SetupCamera();
                  SetNativeControl(_captureElement);
                }
            }
        }

        ...
    }
}

由于除了继承不同外所有代码都是通用的,所以最好使用编译时检查(这种情况下不用担心代码混乱)。

Xamarin.Forms 项目不支持多目标框架,at the opposite it next evolution which is called MAUI will

同时您可以使用 MSBuild SDK Extras SDK 而不是默认的 Microsoft.NET.Sdk an(但请记住它不受官方支持),但最终结果是整洁的(编译时检查)。

  • YourSharedProject.csproj 中将 <Project Sdk="Microsoft.NET.Sdk"> 更改为 <Project Sdk="MSBuild.Sdk.Extras/2.1.2">
  • 设置您的项目所针对的平台及其版本:

例如,如果您的目标是 netstandard2.1 和 iOS 10,则首先从 netstandardxx 开始将 <TargetFramework>netstandard2.1</TargetFramework> 更改为 <TargetFrameworks>netstandard2.1;iOS10</TargetFrameworks>

  • Taget Uwp:<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);uap10.0.17763;netcoreapp3.1;net472</TargetFrameworks>(如果您安装的是 .net framework 4.7.1 而不是 4.7.2,请将 net472 替换为 net471(同样适用于 .net.core 和 uwp 版本)。

最后,您的 .csproj 文件将如下所示:

<Project Sdk="MSBuild.Sdk.Extras/2.1.2">
    <PropertyGroup>
        <TargetFrameworks>netstandard2.1;iOS10</TargetFrameworks>
        <TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">
$(TargetFrameworks);uap10.0.17763;netcoreapp3.1;net472</TargetFrameworks>

所有这些将使您能够在条件编译时检查中使用symbolic constants

public class CustomIOSEditor : 
#if __iOS__
           Editor     //will inherit from this if we are building against iOS
#endif
#if WINDOWS_UWP      //will inherit from this if we are building against uwp
           SfRichTextEditor
#endif
{
    public static readonly BindableProperty StringResultCommandProperty =
        BindableProperty.Create(
            nameof(StringResultCommand),
            typeof(ICommand),
            typeof(CustomIOSEditor),
            default(ICommand));

    public object StringResultCommandParameter
    {
        get => GetValue(StringResultCommandParameterProperty);
        set => SetValue(StringResultCommandParameterProperty, value);
    }
}

针对其他平台版本:

  • Mac 版本 20:Xamarin.Mac20
  • Android 版本 10.0:MonoAndroid10.0
  • tizen 版本 40:tizen40