繁体   English   中英

如何在我自己的 ContentView(自定义控件)中使用 Xamarin.Forms.Setter 类?

[英]How can I use the Xamarin.Forms.Setter class in my own ContentView (custom control)?

我正在创建一个名为AutoAdaptingViewContentView自定义控件。 基本上,它是一个可以处理两个View (FirstContent 和 SecondContent)的网格,它会根据方向、屏幕高度等自动将两个View放在两行或两列中。 现在,我想创建两个附加的BindableProperty命名为 PortraitSetters 和 LandscapeSetters,它们是List<Setter> ,以便此类的使用者可以使用 XAML 使用Setter列表声明 Horizo​​ntalOptions、RequestedHeight 和任何其他相关属性的变体。 当方向改变时,该列表将被扫描,它将使用反射来设置所有需要设置的属性。 问题是,如果我使用这样的列表,它将无法编译,因为它无法从string转换为BindableProperty

这是我的 BindableProperty 声明:

        //
        public static readonly BindableProperty PortraitSettersProperty = BindableProperty.CreateAttached(
            "PortraitSetters",
            typeof(List<Setter>),
            typeof(AutoAdaptingView),
            null
        );

        public static List<Setter> GetPortraitSetters(BindableObject target)
        {
            return (List<Setter>)(target as View).GetValue(PortraitSettersProperty);
        }

        public static void SetPortraitSetters(BindableObject target, List<Setter> value)
        {
            (target as View).SetValue(PortraitSettersProperty, value);
        }

        //
        public static readonly BindableProperty LandscapeSettersProperty = BindableProperty.CreateAttached(
            "LandscapeSetters",
            typeof(List<Setter>),
            typeof(AutoAdaptingView),
            null
        );

        public static List<Setter> GetLandscapeSetters(BindableObject target)
        {
            return (List<Setter>)(target as View).GetValue(LandscapeSettersProperty);
        }

        public static void SetLandscapeSetters(BindableObject target, List<Setter> value)
        {
            (target as View).SetValue(LandscapeSettersProperty, value);
        }

这是一个如何使用它的示例:

<ctrl:AutoAdaptingView>
    <ctrl:AutoAdaptingView.FirstContent>
        <StackLayout Orientation="Vertical"
                     Spacing="16">

            <ctrl:AutoAdaptingView.PortraitSetters>
                <Setter Property="HorizontalOptions" Value="Center"/>
                <Setter Property="VerticalOptions" Value="Start"/>
                <Setter Property="Margin" Value="16, 100, 16, 16"/>
            </ctrl:AutoAdaptingView.PortraitSetters>

            <ctrl:AutoAdaptingView.LandscapeSetters>
                <Setter Property="HorizontalOptions" Value="Center"/>
                <Setter Property="VerticalOptions" Value="Center"/>
                <Setter Property="Margin" Value="16"/>
            </ctrl:AutoAdaptingView.LandscapeSetters>

            <!-- actual content here -->

这就是问题所在:

Cannot convert "HorizontalOptions" into Xamarin.Forms.BindableProperty

显然,我不希望 XAML 神奇地理解Property字段指的是StackLayout BindableProperty,但就像Style类具有TargetType属性一样,它允许它自动将属性名称字符串转换为实际的BindableProperty对象,应该有一种方法可以让我实现相同的方法。

我想到的一个解决方案是创建我自己的 Setter 类,而不是BindableProperty对象,它只需要一个属性名称(因为这是我在实现中实际需要的),但是我不需要创建转换器为了转换值(即"16, 100, 16, 16"new Margin(16, 100, 16, 16) )?

最简单的解决方案是改用一个事件,消费者将在后面的代码中处理该事件,但这会损失代码资源分离的优势。

您可以在 App.xaml 中定义您的样式(全局样式)

<Style x:Key="portraitStyle" TargetType="custom:LabelEntry">
   <Setter Property="HorizontalOptions" Value="Center"/>
            <Setter Property="VerticalOptions" Value="Start"/>
            <Setter Property="Margin" Value="16, 100, 16, 16"/>
</Style>

并且,在您的视图绑定中

Style="{Binding YourProperty , Converter={ StaticResource ConvertStyleKey }}"

带转换器用于:

public class ConvertStyle : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        valueType = (YourModel)value
        if (valueType.YourProperty)
        {
            return Application.Current.Resources["portraitStyle"] as Style;
        }
        else
        {
            //other style
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM