水平StackLayout中的受控帧宽度大小

时间:2016-08-29 17:28:05

标签: c# xaml xamarin xamarin.forms

我正在尝试创建一组由具有不同宽度的帧组成的堆叠水平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。

0 个答案:

没有答案