如何在XAML [Xamarin.Forms]中使用String以外的Type设置自定义属性值

问题描述 投票:2回答:2

在XAML的Xamarin.Forms中,您可以编写如下内容:

<Entry Keyboard="Plain" />

我调查了Entry类,并且Keyboard属性的类型为Xamarin.Forms.Keyboard。但是,如果我创建自己的自定义ContentView并在内部写了这样的内容:

    public static readonly BindableProperty KeyboardProperty = BindableProperty.Create
    (
        propertyName: "Keyboard",
        returnType: typeof(Keyboard),
        declaringType: typeof(MyCustomContentView),
        defaultValue: Keyboard.Default,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: (bindable, oldValue, newValue) =>
        {
            // some unrelated stuff here
        }
    );
    public Keyboard Keyboard
    {
        get => (Keyboard)GetValue(KeyboardProperty);
        set => SetValue(KeyboardProperty, value);
    }

我不能对自己的内容视图使用相同的XAML格式。显然,这是一个简单的字符串,需要Xamarin.Forms.Keyboard类的实例。到目前为止,我已经发现它与KeyboardProperty或绑定无关,但与Keyboard属性本身无关(如果我是对的)。我相信它与ValueConverters有关,当XAML解析器到达此部分时,我必须定义某种形式的字符串到键盘的转换,似乎无法找到我需要做的回答。

c# xaml xamarin.forms converters
2个回答
1
投票

问题的答案在Petzold的漂亮的《 [[Xamarin.Forms》一书中很好地解释了(您可以免费下载here!]。)>

第7章

属性和属性]部分的末尾,您可以阅读
...您可以在XAML中包括自定义类,并且这些类可以具有自定义类型的属性,或者这些属性可以是标准类型,但允许附加值。您所需要做的就是使用C#TypeConverter属性标记这些类型或属性,并提供派生自TypeConverter的类。

还有一些好奇的细节

(从上述书中简单引用)在那章中,Petzold通过给出一个带有Label的示例来说明这一点:

<Label Text="Hello from XAML!" IsVisible="True" Opacity="0.75" HorizontalTextAlignment="Center" VerticalOptions="CenterAndExpand" TextColor="Blue" BackgroundColor="#FF8080" FontSize="Large" FontAttributes="Bold,Italic" />

然后继续说明XAML如何设置这些属性。

XAML的简洁性主要来自属性值的简洁性,例如,使用单词“ Large”而不是对Device.GetNamedSize方法的调用。这些缩写未内置到XAML解析器中。相反,XAML解析器由专门为此目的定义的各种转换器类辅助。

当XAML解析器遇到Label元素时,它可以使用反射来确定Xamarin.Forms是否具有一个名为Label的类,如果是,则可以实例化该类。现在可以初始化该对象了。 Text属性是字符串类型,并且属性值只是分配给该属性。

Label的IsVisible和Opacity属性分别为bool和double类型,它们与您期望的一样简单。 XAML解析器使用Boolean.Parse和Double.Parse方法转换属性值。 Boolean.Parse方法不区分大小写,但是在XAML中,布尔值通常大写为“ True”和“ False”。 Double.Parse方法传递了CultureInfo.InvariantCulture参数,因此转换不依赖于程序员或用户的本地文化。

Label的Horizo​​ntalTextAlignment属性的类型为TextAlignment,它是一个枚举。对于任何属于枚举类型的属性,XAML解析器都使用Enum.Parse方法将字符串从值转换为值。

The VerticalOptions属性是LayoutOptions类型的结构。当XAML解析器使用反射引用LayoutOptions结构时,它发现该结构具有定义的C#属性:

[TypeConverter (typeof(LayoutOptionsConverter))] public struct LayoutOptions { … }

TypeConverter属性由名为TypeConverterAttribute的类支持。 LayoutOptions上的此特定TypeConverter属性引用了一个名为LayoutOptionsConverter的类,该类派生自一个名为TypeConverter的公共抽象类,该类定义了名为CanConvertFrom和ConvertFrom的方法。当XAML解析器遇到此TypeConverter属性时,它将实例化LayoutOptionsConverter。 XAML中的VerticalOptions属性被分配了字符串“ Center”,因此XAML解析器将该“ Center”字符串传递给LayoutOptionsConverter的ConvertFrom方法,然后弹出LayoutOptions值。这被分配给Label对象的VerticalOptions属性。

完全回答问题。创建此类:

using System; using Xamarin.Forms; public class KeyboardTypeConverter : TypeConverter { public override bool CanConvertFrom(Type sourceType) { return sourceType == typeof(string); } public override object ConvertFromInvariantString(string value) { switch (value) { case "Chat": return Keyboard.Chat; case "Email": return Keyboard.Email; case "Numeric": return Keyboard.Numeric; case "Plain": return Keyboard.Plain; case "Telephone": case "Phone": return Keyboard.Telephone; case "Text": return Keyboard.Text; case "Url": return Keyboard.Url; default: return Keyboard.Default; } } }

然后将TypeConverter属性添加到Keyboard属性:

using System.Reflection; using Xamarin.Forms; using Xamarin.Forms.Xaml; [TypeConverter(typeof(KeyboardTypeConverter))] public Keyboard Keyboard { get => (Keyboard)GetValue(KeyboardProperty); set => SetValue(KeyboardProperty, value); }


1
投票
完全回答问题。创建此类:
© www.soinside.com 2019 - 2024. All rights reserved.