【问题标题】:How to use different base class in custom control depending on platform target?如何根据平台目标在自定义控件中使用不同的基类?
【发布时间】:2021-04-14 21:41:42
【问题描述】:

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

现在我想知道如何像可共享类一样创建,因为它们具有相同的可绑定属性,而不是像我目前所做的那样,即在它们之上创建 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>
    

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

这些是我今天拥有的 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:

Mac 操作系统:

设置:

错误:

【问题讨论】:

  • 现在检查。所以这是我强调的,前两个你可以忽略
  • 是的,我做到了。还重新启动了视觉工作室。还是同样的问题。
  • 顺便说一句,我使用 xamarn 表单。
  • 是的,我当然知道 XF(否则就没有意义),.__MACOS__。似乎按预期工作,代码中的一切似乎都很好,抱歉我现在不知道。
  • 好的。我不需要更改任何特定于 MacOS 的内容?

标签: c# xamarin xamarin.forms custom-controls multitargeting


【解决方案1】:

因为除了继承之外,所有代码都是常见的,它更好地使用编译时检查(在这种情况下,不用担心代码乱乱)。

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

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

  • YourSharedProject.csproj change &lt;Project Sdk="Microsoft.NET.Sdk"&gt;&lt;Project Sdk="MSBuild.Sdk.Extras/2.1.2"&gt;
  • 设置项目目标的平台及其版本:

如果您定位NetStandard2.1和iOS 10,则通过首先以@ 987654330开始更改&lt;TargetFramework&gt;netstandard2.1&lt;/TargetFramework&gt;至987654329 @。

  • Taget UWP:&lt;TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' "&gt;$(TargetFrameworks);uap10.0.17763;netcoreapp3.1;net472&lt;/TargetFrameworks&gt;(如果您拥有.NET Framework 4.7.1而不是4.7.2,请替换@ 9876543333 net471(同样的.NET.Core和UWP版本)。 Li >

最后,您的.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

【讨论】:

  • 哦哇,确实非常好。我现在会告诉它,看看它是否有效。任何想法如果有任何已知的错误(因为它尚未正式支持)? span>
  • 您是否知道何时何时键入麦斯科斯(例如)? v2.0 targetframeworkversion> xamarin.mac targetframeworkidifier>这是我在挖掘它的.csproj span>时发现的目标version
  • 确实Xamarin.Mac +版本附加而没有任何空间。我已经更新了我的答案。对于错误,您可以随时拍摄我已链接的repo并查看/问题。 span>
  • HMM具有问题。它需要20秒的编译器来计算自定义类的缺少类型。不确定它是否因为XAMARIN MAC不是2.1。支持的?我不确定如何使其成为2.1兼容。 span>
  • i测试两个 - netstandard2.1; xamarin.mac20 targetframeworks>也 netstandard2.0; xamarin.mac20 targetframeworks> span>
【解决方案2】:

你要找的是SetNativeControl()

例如检查这个例子,

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

在此处粘贴上面链接中的相同示例

注意 - 下面示例中的 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);
                }
            }
        }

        ...
    }
}

【讨论】:

  • 在这种情况下使用自定义渲染器不是矫枉过正吗?我不明白这将如何解决“重复代码”?
  • 是的,那么我必须为平台编写特定于平台的代码,我认为应该有更好的方法来解决它。
猜你喜欢
  • 2021-01-24
  • 2021-12-28
  • 2019-12-28
  • 1970-01-01
  • 1970-01-01
  • 2022-08-15
  • 2013-07-15
  • 1970-01-01
  • 2023-01-20
相关资源
最近更新 更多