如何根据平台目标在自定义控件中使用不同的基础class?
How to use different base class in custom control depending on platform target?
我有一个用于 iOS 的自定义编辑器,但对于 UWP,我使用另一个名为 SfRichTextEditor
.
的编辑器
现在我想知道如何创建一个可共享的 class,因为它们具有相同的可绑定属性,而不是做我目前所做的,即在它们之上创建一个 ContentView
,这导致:
出于性能目的进行不必要的嵌套
重复代码
某些绑定似乎有问题(未验证,但有些奇怪)。
<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()
.
例如检查这个例子,
在此处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
我有一个用于 iOS 的自定义编辑器,但对于 UWP,我使用另一个名为 SfRichTextEditor
.
现在我想知道如何创建一个可共享的 class,因为它们具有相同的可绑定属性,而不是做我目前所做的,即在它们之上创建一个 ContentView
,这导致:
出于性能目的进行不必要的嵌套
重复代码
某些绑定似乎有问题(未验证,但有些奇怪)。
<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);
}
}
最新线索**
苹果操作系统:
设置:
错误:
您要找的是SetNativeControl()
.
例如检查这个例子,
在此处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