如何根据 Xamarin (XAML) 中的平台将编辑器的不同属性绑定到同一变量



我正在尝试将CustomEditor的属性PlainText(这是我在自定义编辑器中创建的双向可绑定属性(绑定到变量KeyStringiOS,并在Android时将属性Text绑定到KeyString

我知道PlainTextKeyString的绑定在iOS工作正常(我已经测试以确保这一点(,但是TextKeyString的绑定Android失败,System.ArgumentNullExceptionValue cannot be null. Parameter name: binding

智能感知还强调了我的代码中在x:TypeAgruments中使用BindingBase的部分。对于第一部分,智能感知说:PlainText does not support values of type OnPlatform(BindingBase),但是当我在iOS模拟器上运行它时,代码仍然有效。它为我提供了代码Android绑定部分的错误Text does not support values of type OnPlatform(BindingBase),即无法运行的 XAML 部分。

下面是我的XAML代码,知道我可能做错了什么吗?

<Frame Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" BorderColor="Black" Margin="0" Padding="0">
<controls:CustomEditor HeightRequest="80" IsPassword="True">
<controls:CustomEditor.PlainText>
<OnPlatform x:TypeArguments="BindingBase">
<On Platform="iOS" Value="{Binding KeyString}"/>
</OnPlatform>
</controls:CustomEditor.PlainText>
<controls:CustomEditor.Text>
<OnPlatform x:TypeArguments="BindingBase">
<On Platform="Android" Value="{Binding KeyString}"/>
</OnPlatform>
</controls:CustomEditor.Text>
<controls:CustomEditor.Effects>
<controls:PasswordEffect>
</controls:PasswordEffect>
</controls:CustomEditor.Effects>
</controls:CustomEditor>
</Frame>

在我的自定义编辑器类中,我有以下代码:

using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace MyApp.CustomControls
{
public class CustomEditor : Editor
{
public static readonly BindableProperty IsPasswordProperty =
BindableProperty.Create(nameof(IsPassword), typeof(bool), typeof(CustomEditor), false);
public static readonly BindableProperty PlainTextProperty =
BindableProperty.Create(nameof(PlainText),
typeof(string),
typeof(CustomEditor),
String.Empty,
defaultBindingMode:BindingMode.TwoWay,
propertyChanged:OnPlainTextChanged);
public bool IsPassword
{
get { return (bool)GetValue(IsPasswordProperty); }
set { SetValue(IsPasswordProperty, value); }
}
public string PlainText {
get { return (string)GetValue(PlainTextProperty); }
set { SetValue(PlainTextProperty, value); }
}
private static void OnPlainTextChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (CustomEditor)bindable;
if (newValue != null)
{
control.PlainText = newValue.ToString();
}
}
}
}

由于我不喜欢与OnPlatform一起工作,我想提出我在评论中提到的解决方法。

CustomEditor中添加以下代码:

public static BindableProperty CustomTitleProperty = BindableProperty.Create(
propertyName: nameof(CustomTitle),
returnType: typeof(string),
declaringType: typeof(CustomEditor),
defaultValue: null);
public string CustomTitle
{
get { return (string)GetValue(CustomTitleProperty); }
set { SetValue(CustomTitleProperty, value); }
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if(propertyName==CustomTitleProperty.PropertyName)
{
SetCustomTitle();
}
}
private void SetCustomTitle()
{
switch(Device.RuntimePlatform)
{
case Device.iOS:
{
PlainText = CustomTitle;
return;
}
case Device.Android:
{
Text = CustomTitle;
return;
}
default:
{
throw new NotSupportedException($"{Device.RuntimePlatform} not supported in {nameof(SetCustomTitle)}");
}
}
}

我在那里所做的是,我只是将 OnPlatform 代码移动到您的控件中,因此您可以保持 xaml 代码更干净。

使用这种方法,您应该能够像

<controls:CustomEditor HeightRequest="80" IsPassword="True" CustomTitle="{Binding KeyString}">
<controls:CustomEditor.Effects>
<controls:PasswordEffect/>
</controls:CustomEditor.Effects>
</controls:CustomEditor>

OnPlatform 的 x:TypeArguments 表示您要绑定的值类型,在您的情况下KeyString类型为string。看看平台。

<Frame Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" BorderColor="Black" Margin="0" Padding="0">
<controls:CustomEditor HeightRequest="80" IsPassword="True">
<controls:CustomEditor.PlainText>
<OnPlatform x:TypeArguments="{x:Type x:String}">
<On Platform="iOS" Value="{Binding KeyString}"/>
</OnPlatform>
</controls:CustomEditor.PlainText>
<controls:CustomEditor.Text>
<OnPlatform x:TypeArguments="{x:Type x:String}">
<On Platform="Android" Value="{Binding KeyString}"/>
</OnPlatform>
</controls:CustomEditor.Text>
<controls:CustomEditor.Effects>
<controls:PasswordEffect>
</controls:PasswordEffect>
</controls:CustomEditor.Effects>
</controls:CustomEditor>
</Frame>

相关内容

最新更新