C# 如何基于Xamarin(XAML)中的平台将编辑器的不同属性绑定到同一变量
我正在尝试将C# 如何基于Xamarin(XAML)中的平台将编辑器的不同属性绑定到同一变量,c#,xaml,xamarin,xamarin.forms,data-binding,C#,Xaml,Xamarin,Xamarin.forms,Data Binding,我正在尝试将CustomEditor的属性PlainText(这是我在我的CustomEditor中创建的双向可绑定属性)绑定到启用iOS时的变量KeyString,并在启用Android时将属性Text绑定到KeyString 我知道,在iOS上,将明文绑定到按键串可以正常工作(我已经进行了测试以确保这一点),但是安卓将文本绑定到按键串会在系统中失败。ArgumentNullException值不能为空。参数名称:绑定 另外,IntelliSense在x:TypeAgruments中使用Bin
CustomEditor
的属性PlainText
(这是我在我的CustomEditor中创建的双向可绑定属性)绑定到启用iOS
时的变量KeyString
,并在启用Android
时将属性Text
绑定到KeyString
我知道,在iOS
上,将明文
绑定到按键串
可以正常工作(我已经进行了测试以确保这一点),但是安卓
将文本
绑定到按键串
会在系统中失败。ArgumentNullException
值不能为空。参数名称:绑定
另外,IntelliSense在x:TypeAgruments
中使用BindingBase
的代码部分加下划线。对于第一部分,Intellisense说:明文不支持OnPlatform(BindingBase)
类型的值,但是当我在我的iOS
模拟器上运行它时,代码仍然有效。它给我的错误是,文本不支持代码的Android
绑定部分的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>
OnPlatform的x:TypeArguments表示要绑定的值的类型,在本例中,
KeyString
的类型为string
。看一看
OnPlatform的x:TypeArguments表示要绑定的值的类型,在您的示例中,
键串
的类型为字符串
。看一看
由于我不喜欢在平台上使用
,我想提出一个我在评论中提到的解决方法
在您的CustomEditor
中添加以下代码:
公共静态BindableProperty CustomTitleProperty=BindableProperty.Create(
propertyName:nameof(CustomTitle),
returnType:typeof(字符串),
declaringType:typeof(CustomEditor),
默认值:空);
公共字符串自定义标题
{
get{return(string)GetValue(CustomTitleProperty);}
set{SetValue(CustomTitleProperty,value);}
}
受保护的重写无效OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
base.OnPropertyChanged(propertyName);
如果(propertyName==CustomTitleProperty.propertyName)
{
SetCustomTitle();
}
}
私有void SetCustomTitle()
{
交换机(设备运行时平台)
{
case Device.iOS:
{
纯文本=自定义标题;
返回;
}
case设备。Android:
{
文本=自定义标题;
返回;
}
违约:
{
抛出新的NotSupportedException($“{nameof(SetCustomTitle)}中不支持{Device.RuntimePlatform}”);
}
}
}
我所做的只是将平台上的代码移到您的控件中,这样您就可以保持xaml代码更干净
使用这种方法,您应该能够像这样使用它
由于我不喜欢在平台上使用
,我想提出一个我在评论中提到的解决方法
在您的CustomEditor
中添加以下代码:
公共静态BindableProperty CustomTitleProperty=BindableProperty.Create(
propertyName:nameof(CustomTitle),
returnType:typeof(字符串),
declaringType:typeof(CustomEditor),
默认值:空);
公共字符串自定义标题
{
get{return(string)GetValue(CustomTitleProperty);}
set{SetValue(CustomTitleProperty,value);}
}
受保护的重写无效OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
base.OnPropertyChanged(propertyName);
如果(propertyName==CustomTitleProperty.propertyName)
{
SetCustomTitle();
}
}
私有void SetCustomTitle()
{
交换机(设备运行时平台)
{
case Device.iOS:
{
纯文本=自定义标题;
返回;
}
case设备。Android:
{
文本=自定义标题;
返回;
}
违约:
{
抛出新的NotSupportedException($“{nameof(SetCustomTitle)}中不支持{Device.RuntimePlatform}”);
}
}
}
我所做的只是将平台上的代码移到您的控件中,这样您就可以保持xaml代码更干净
使用这种方法,您应该能够像这样使用它
您为什么不能在CustomEditor中根据平台设置文本?在这种情况下,您可以将值绑定到控件中的属性和处理平台什么是CustomEditor?有取景模型吗?[m.v.c.e]please@lawiluk谢谢你的评论,这听起来很合理,你能进一步解释一下吗?关于如何做到这一点,我只是用一个简单的绑定测试你的代码,它在Android端工作,你能分享更多的代码来重现这个问题吗?@JackHua MSFT我分享了更多的代码,希望这会有所帮助,如果您想查看更具体的内容,请告诉我您为什么不能在CustomEditor中根据平台设置文本?在这种情况下,您可以将值绑定到属性和handl
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();
}
}
}
}
<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>