Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
177 views
in Technique[技术] by (71.8m points)

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

I have a custom editor that I use for iOS, but for UWP I use another editor called SfRichTextEditor.

Now I wonder how I can create like a shareable class, since they have the same bindableproperties instead of doing what I currently do, which is creating a ContentView on top of them, which is causing:

  1. unnecessary nesting for performance purposes

  2. duplicate code

  3. seems to have trouble with some bindings (not verified, but something strange).

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

So instead of this approach, I want to have a shareable base class if possible, to reuse the code.

These are the x2 controls that I have today.

My iOS custom control:

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);
    }
}

My UWP custom control:

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);
    }
}

Latest clue** enter image description here UPDATE** Shared .csproj: enter image description here

MacOS: enter image description here

Settings: enter image description here

Error: enter image description here

question from:https://stackoverflow.com/questions/65641587/how-to-use-different-base-class-in-custom-control-depending-on-platform-target

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since all code is common except the inheritance is different, it better to use a compile-time check (no worries of code being messy in this case).

Xamarin.Forms project does not support Multi-targeting frameworks, at the opposite it next evolution which is called MAUI will.

Meanwhile you can use MSBuild SDK Extras SDK instead of the default Microsoft.NET.Sdk an (but keep in mind that it is not officially supported), but end result is neat (compile-time check).

  • In YourSharedProject.csproj change <Project Sdk="Microsoft.NET.Sdk"> to <Project Sdk="MSBuild.Sdk.Extras/2.1.2">.
  • Setup the platforms that your projects is targeting and their version:

Example if you target netstandard2.1 and iOS 10 then change <TargetFramework>netstandard2.1</TargetFramework> to <TargetFrameworks>netstandard2.1;iOS10</TargetFrameworks> by starting with the netstandardxx first.

  • Taget Uwp: <TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);uap10.0.17763;netcoreapp3.1;net472</TargetFrameworks> (if you have .net framework 4.7.1 installed instead of 4.7.2, replace net472 by net471 (same thing for .net.core and uwp versions).

At the end, your .csproj file starts will looks like this:

<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>

All this will enable you to use the symbolic constants in a conditional compile time check:

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);
    }
}

For targeting other platforms-version:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...