滚动内容
请记住,Xamarin.Forms程序可以访问.NET基类库,并可以使用.NET反射来获取有关程序集中定义的所有类和结构的信息,例如Xamarin.Forms.Core。 这表明可以自动获取Color结构的静态字段和属性。
大多数.NET反射都以Type对象开始。 您可以使用C#typeof运算符为任何类或结构获取Type对象。 例如,表达式typeof(Color)为Color结构返回一个Type对象。
在PCL中可用的.NET版本中,名为GetTypeInfo的Type类的扩展方法返回一个TypeInfo对象,从中可以获取附加信息。 虽然这在下面的程序中不是必需的; 它需要为Type类定义的其他扩展方法,名为GetRuntimeFields和GetRuntimeProperties。 它们以FieldInfo和PropertyInfo对象的集合的形式返回类型的字段和属性。 从这些,名称以及属性的值可以获得。
这由ReflectedColors程序演示。 ReflectedColorsPage.cs文件需要System.Reflection的using指令。
在两个单独的foreach语句中,ReflectedColorsPage类遍历Color结构的所有字段和属性。 对于所有返回Color值的公共静态成员,这两个循环调用CreateColorLabel以创建一个带有Color值和名称的Label,然后将该Label添加到StackLayout。
通过包含所有公共静态字段和属性,程序会列出Color.Transparent,Color.Default和Color.Accent以及前面程序中显示的17个静态字段。 一个单独的CreateColorLabel方法为每个项目创建一个Label视图。 以下是ReflectedColorsPage类的完整列表。
点击(此处)折叠或打开
public class ReflectedColorsPage : ContentPage
{
public ReflectedColorsPage()
{
StackLayout stackLayout = new StackLayout();
// Loop through the Color structure fields.
foreach (FieldInfo info in typeof(Color).GetRuntimeFields())
{
// Skip the obsolete (i.e. misspelled) colors.
if (info.GetCustomAttribute<ObsoleteAttribute>() != null)
continue;
if (info.IsPublic &&
info.IsStatic &&
info.FieldType == typeof(Color))
{
stackLayout.Children.Add(
CreateColorLabel((Color)info.GetValue(null), info.Name));
}
}
// Loop through the Color structure properties.
foreach (PropertyInfo info in typeof(Color).GetRuntimeProperties())
{
MethodInfo methodInfo = info.GetMethod;
if (methodInfo.IsPublic &&
methodInfo.IsStatic &&
methodInfo.ReturnType == typeof(Color))
{
stackLayout.Children.Add(
CreateColorLabel((Color)info.GetValue(null), info.Name));
}
}
Padding = new Thickness(5, Device.OnPlatform(20, 5, 5), 5, 5);
// Put the StackLayout in a ScrollView.
Content = new ScrollView
{
Content = stackLayout
};
}
Label CreateColorLabel(Color color, string name)
{
Color backgroundColor = Color.Default;
if (color != Color.Default)
{
// Standard luminance calculation.
double luminance = 0.30 * color.R +
0.59 * color.G +
0.11 * color.B;
backgroundColor = luminance > 0.5 ? Color.Black : Color.White;
}
// Create the Label.
return new Label
{
Text = name,
TextColor = color,
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
BackgroundColor = backgroundColor
};
}
}
在构造函数的最后,StackLayout被设置为ScrollView的Content属性,然后将其设置为页面的Content属性。
该类中的CreateColorLabel方法试图通过设置一个配置背景来使每个颜色可见。 该方法基于红色,绿色和蓝色分量的标准加权平均值计算亮度值,然后选择白色或黑色的背景。
此技术对透明无效,因此该项目根本无法显示,并且该方法将Color.Default视为特殊情况,并在Color.Default背景下显示该颜色(无论它可能是什么)。
以下是结果,这些结果仍然不够美观:
但是您可以滚动显示,因为StackLayout是ScrollView的子项。
StackLayout和ScrollView在类层次结构中相关。 StackLayout派生自Layout ,你会记得Layout 类定义了StackLayout继承的Children属性。 通用布局类派生自非布局布局类,而ScrollView也派生自此非布局布局。 理论上,ScrollView是一种布局对象 - 即使它只有一个子对象。
从截图中可以看到,Label的背景颜色扩展到StackLayout的全部宽度,这意味着每个Label都与StackLayout一样宽。
让我们试验一下,以更好地理解Xamarin.Forms布局。 对于这些实验,您可能需要临时给出StackLayout和ScrollView独特的背景颜色:
点击(此处)折叠或打开
public ReflectedColorsPage()
{
StackLayout stackLayout = new StackLayout
{
BackgroundColor = Color.Blue
};
…
Content = new ScrollView
{
BackgroundColor = Color.Red,
Content = stackLayout
};
}