简体   繁体   English

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

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

I am creating a ContentView custom control which I named AutoAdaptingView .我正在创建一个名为AutoAdaptingViewContentView自定义控件。 Basically, it's a grid which can handle two View (FirstContent and SecondContent), and it will automatically put the two View in either two rows or two columns, depending on the orientation, screen height, etc. Now, I want to create two attached BindableProperty named PortraitSetters and LandscapeSetters, which are List<Setter> , so that the consumer of this class can use XAML to declare variations of HorizontalOptions, RequestedHeight and any other relevant property using a list of Setter .基本上,它是一个可以处理两个View (FirstContent 和 SecondContent)的网格,它会根据方向、屏幕高度等自动将两个View放在两行或两列中。 现在,我想创建两个附加的BindableProperty命名为 PortraitSetters 和 LandscapeSetters,它们是List<Setter> ,以便此类的使用者可以使用 XAML 使用Setter列表声明 Horizo​​ntalOptions、RequestedHeight 和任何其他相关属性的变体。 That list will be scanned when the orientation changes, and it will use Reflection to set all the properties that need to be setted.当方向改变时,该列表将被扫描,它将使用反射来设置所有需要设置的属性。 The problem is that if I use such list, it won't compile because it cannot convert from string to BindableProperty .问题是,如果我使用这样的列表,它将无法编译,因为它无法从string转换为BindableProperty

Here's my BindableProperty declaration:这是我的 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);
        }

Here's an example of how it would be used:这是一个如何使用它的示例:

<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 -->

And here's the problem:这就是问题所在:

Cannot convert "HorizontalOptions" into Xamarin.Forms.BindableProperty

Obviously I don't expect XAML to magically understand that the Property field refers to a StackLayout BindableProperty, but just in the same way that the Style class has a TargetType property that permits it to automatically convert the property name string to the actual BindableProperty object, there should be a way that permits me to implement the same.显然,我不希望 XAML 神奇地理解Property字段指的是StackLayout BindableProperty,但就像Style类具有TargetType属性一样,它允许它自动将属性名称字符串转换为实际的BindableProperty对象,应该有一种方法可以让我实现相同的方法。

A solution I thought about was to create my own Setter class that, instead of a BindableProperty object, it only takes a property name (since that is what I actually need in the implementation), but then wouldn't I need to create a converter in order to transform the values (ie "16, 100, 16, 16" to new Margin(16, 100, 16, 16) )?我想到的一个解决方案是创建我自己的 Setter 类,而不是BindableProperty对象,它只需要一个属性名称(因为这是我在实现中实际需要的),但是我不需要创建转换器为了转换值(即"16, 100, 16, 16"new Margin(16, 100, 16, 16) )?

The simplest solution would be to use an event instead, that the consumer will handle in the code behind, but this would cost the advantages of code-resource separation.最简单的解决方案是改用一个事件,消费者将在后面的代码中处理该事件,但这会损失代码资源分离的优势。

You could define your styles in App.xaml (Global styling)您可以在 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>

and, in your View Binding并且,在您的视图绑定中

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

With a converter for:带转换器用于:

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.

相关问题 如何在Xamarin形式的ContentView中使用Prism MVVM? - How do I use Prism MVVM with a ContentView in Xamarin Forms? 如何使我的自定义控件在 Xamarin Forms 中浮动? - How do I make my Custom Control float in Xamarin Forms? 如何以Xamarin形式在XAML文件中使用C#类 - How can I use my C# class in my XAML file in xamarin forms Xamarin.Forms:我可以声明一个必须是 ContentView 的接口吗 - Xamarin.Forms: can I declare an interface that has to be a ContentView Xamarin Forms DateTimePicker 自定义 ContentView 可绑定属性 - Xamarin Forms DateTimePicker custom ContentView bindable property Xamarin Forms:具有自定义渲染器的高级ContentView组件 - Xamarin Forms : advanced ContentView component with custom renderer 如何使用从主窗体上的内置控件继承的自定义控件类? - How can I use a custom control class that inherits from a built-in control on my main form? 如何在10秒后正确创建自己的功能以Xamarin形式拍摄照片? - How can I correctly create my own function to take a photo in Xamarin forms after 10 seconds? 使用ListView时,如何在Xamarin Forms中将自定义控件绑定设置为父视图模型属性? - How can I set custom control binding to parent view model property in Xamarin Forms when using a ListView? 如何创建和初始化自定义Xamarin表单控件 - How Do I Create and Initialize a Custom Xamarin Forms Control
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM