我正在尝试创建一组由具有不同宽度的帧组成的堆叠水平StackLayouts。最终目标是创建一个计划视图(一次查看多个日历),与Outlook中可能的不同(参见附图)。
所需输出:http://i.stack.imgur.com/1c0mu.png
在尝试这样做时,我注意到只有当所有帧具有相同的精确宽度时,添加到水平StackLayout的帧宽度才会匹配WidthRequest。如果框架的宽度不同,则宽度和宽度请求不匹配。
这是XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinSample.SamplePage1">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<ScrollView x:Name="FrozenBandDataScrollView"
Orientation="Horizontal">
<StackLayout VerticalOptions="Start"
HorizontalOptions="Start"
Orientation="Vertical"
Spacing="0"
BackgroundColor="Silver"
WidthRequest="3600"
x:Name="FrozenBandDataStackLayout">
</StackLayout>
</ScrollView>
</ContentPage>
以下是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace XamarinSample
{
public partial class SamplePage1 : ContentPage
{
TapGestureRecognizer tapFrameRecognizer = new TapGestureRecognizer();
public SamplePage1()
{
InitializeComponent();
addDataPoints();
}
public void addDataPoints()
{
tapFrameRecognizer.Tapped += (s, e) =>
{
Frame f = s as Frame;
Label l = f.Content as Label;
l.Text = "R:" + f.WidthRequest;
l.Text += ", W: " + f.Width;
l.Text += "\nR: " + f.HeightRequest;
l.Text += ", H: " + f.Height;
};
FrozenBandDataStackLayout.Children.Add(getStackLayoutWithDimensions(70, 3600));
FrozenBandDataStackLayout.Children.Add(getStackLayoutWithDimensions(70, 3600));
FrozenBandDataStackLayout.Children.Add(getStackLayoutWithDimensions(70, 3600));
}
public static double randomNumber(int start, int end){return (new Random()).Next(start, end);}
public StackLayout getStackLayoutWithDimensions(double height, double width)
{
StackLayout sl = new StackLayout {
VerticalOptions = LayoutOptions.Start,
HorizontalOptions = LayoutOptions.Start,
Orientation = StackOrientation.Horizontal,
WidthRequest = width,
HeightRequest = height,
Spacing = 0
};
//OPTION 1: randomly calculated width (total = 3600) -- does not work :(
int minFrameWidth = 1;
int maxFrameWidth = 500;
double currentWidth = 0;
while ((currentWidth + maxFrameWidth) < width)
{
double frameWidth = randomNumber(minFrameWidth, maxFrameWidth);
currentWidth += frameWidth;
sl.Children.Add(getFrameWithDimensions(height, frameWidth));
}
sl.Children.Add(getFrameWithDimensions(height, width-currentWidth));
//OPTION 2: specific homogeneous width (total = 3600) -- works :)
/*
for (int i = 0; i < 12; i++)
{
sl.Children.Add(getFrameWithDimensions(height, 300));
}
*/
//OPTION 3: specific altering width (total = 3600) -- does not work :(
/*
for (int i = 0; i < 12; i++)
{
if (i % 2 == 0) {
sl.Children.Add(getFrameWithDimensions(height, 200));
}else
{
sl.Children.Add(getFrameWithDimensions(height, 400));
}
}
*/
return sl;
}
public Frame getFrameWithDimensions(double height, double width)
{
Frame frame = new Frame
{
BackgroundColor = Color.Gray,
OutlineColor = Color.Black,
HasShadow = false,
HorizontalOptions = LayoutOptions.Start,
WidthRequest = width,
VerticalOptions = LayoutOptions.Start,
HeightRequest = height,
Content = new Label
{
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
TextColor = Color.Black,
FontFamily = "Arial",
FontSize = 8,
Text = "test"
}
};
frame.GestureRecognizers.Add(tapFrameRecognizer);
return frame;
}
}
}
以下是三种不同的输出:http://forums.xamarin.com/discussion/74391/controlled-frame-width-size-in-a-horizontal-stacklayout
有没有人知道确保WidthRequest与实际宽度匹配的方法?
此外,有人可以想到另一种可能的Xamarin Forms解决方案吗?我尝试使用网格,但它确实很慢(因为它不适合这种类型的使用)。像水平ListView那样拥有数据绑定的东西会很好。
注意:此应用需要适用于iOS,Windows UWP以及可能的Android。