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:
unnecessary nesting for performance purposes
duplicate code
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);
}
}
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).
YourSharedProject.csproj
change <Project Sdk="Microsoft.NET.Sdk">
to <Project Sdk="MSBuild.Sdk.Extras/2.1.2">
.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.
<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:
Xamarin.Mac20
MonoAndroid10.0
tizen40