在ViewCell中共享Grid-Column的宽度?

时间:2016-04-12 21:53:54

标签: c# xamarin.forms

我希望我的ListViews ViewCell中的列具有相同的大小。它当前设置为auto,最宽的名称应该赢,所有其他列应设置为最宽的标签宽度。目前,它们在每一行都有不同的宽度。

ListView ItemTemplate示例:

<ViewCell>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" /> /
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Text="{Binding Name}"/>
[....]

在WPF中,我们有属性SharedSizeGroup,在Xamarin.Forms中有类似的东西吗? 是否存在没有太多黑客攻击的解决方法?

2 个答案:

答案 0 :(得分:2)

不幸的是,不 - 没有这样的财产。

这是一项相当困难的事情,因为您需要先测量所有行,然后才能确定哪一行具有最宽的文本。没有跨平台的方法来做到这一点。有很多方法可以在Android和iOS的平台级别上进行,但我认为WinPhone还没有办法。

[编辑以反映评论中确定的更好方法]:

另一种方法是使用OneWayToSource绑定并跟踪每个列表视图行的ColumnDefinition条目。

XamlPage.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="FormsSandbox.XamlPage">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness" iOS="0,20,0,0" Android="0" WinPhone="0"/>
    </ContentPage.Padding>

    <AbsoluteLayout>
        <ListView x:Name="MyLV" AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid RowSpacing="0" ColumnSpacing="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Label Grid.Column="0" Text="{Binding .}" MinimumWidthRequest="50" HorizontalOptions="StartAndExpand" SizeChanged="LabelSizeChanged" />
                            <Label Grid.Column="1" Text="Second Column"/>
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </AbsoluteLayout>

</ContentPage>

XamlPage.xaml.cs:

using System;
using Xamarin.Forms;
using System.Collections.Generic;

namespace FormsSandbox
{
    public partial class XamlPage : ContentPage
    {
        private double _colSize = 0.0;
        private List<ColumnDefinition> _columns = new List<ColumnDefinition>();

        public XamlPage ()
        {
            InitializeComponent ();

            var data = new List<string> ();

            data.Add ("Lorem ipsum");
            data.Add ("Foo");
            data.Add ("Dolor semet");
            data.Add ("Test");
            data.Add (".");
            data.Add ("Xamarin Forms Is Great");
            data.Add ("Short");
            data.Add ("Longer than Short");
            data.Add ("");
            data.Add ("Hyphenated");
            data.Add ("Non-hyphenated");
            data.Add ("Ironic, eh?");

            MyLV.ItemsSource = data;
        }

        public void LabelSizeChanged (object sender, EventArgs e)
        {
            var label = (Label)sender;
            var grid = (Grid)label.Parent;
            var column = grid.ColumnDefinitions [0];
            if (!_columns.Contains (column)) {
                _columns.Add (column);
            }
            var adjustments = new List<ColumnDefinition> ();
            if (label.Width > _colSize) {
                _colSize = label.Width;
                adjustments.AddRange (_columns);
            } else {
                adjustments.Add (column);
            }
            foreach (var col in adjustments) {
                col.Width = new GridLength (_colSize);
            }
        }
    }
}

Screenshot of current solution

答案 1 :(得分:0)

虽然目前的答案在MVVM等方面实际上是一个hacky解决方案,但我将其标记为是。我认为这对我和我的小项目来说是一个可以接受的解决方案。这就是我接受答案的原因。如果还有其他选择,请告诉我/我们。