我正在创建一个ContentView
名为AutoAdaptingView
. 基本上,它是一个可以处理两个View
(FirstContent 和 SecondContent)的网格,它会View
根据方向、屏幕高度等自动将这两个放在两行或两列中。 现在,我想创建两个附加的BindableProperty
名为 PortraitSetters和 LandscapeSetters,它们是List<Setter>
,以便此类的使用者可以使用 XAML 来声明 HorizontalOptions、RequestedHeight 和使用Setter
. 当方向改变时,该列表将被扫描,它将使用反射来设置所有需要设置的属性。问题是,如果我使用这样的列表,它将无法编译,因为它无法从 转换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
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句