简体   繁体   中英

Xamarin.Forms - Adjusting height of CollectionView to be minimum size to fit children

I have a CollectionView with a few items in it. I'm trying to adjust the size of the CollectionView to be just big enough to fit all of its children. Right now, it's much larger than the amount of children it has. 在此处输入图像描述

The Blue color represents the size of the CollectionView. As you can see, it's well beyond the size of it's children. I'd like it to fit them perfectly, or at the very least be closer to the same size.

I don't have any height requests on any of the elements on the page, including the CollectionView.

Here's my code. It's not particularly pretty at the moment, but it's a work in progress.

<StackLayout>
                <CollectionView x:Name="assessmentsCollectionView"
                                BackgroundColor="Blue">
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <StackLayout Spacing="10"
                                         Padding="5">
                                <Frame CornerRadius="5"
                                       Padding="0"
                                       HorizontalOptions="FillAndExpand"
                                       VerticalOptions="FillAndExpand">
                                    <StackLayout Orientation="Horizontal">
                                        <Frame Padding="5"
                                               CornerRadius="0"
                                               WidthRequest="50">
                                            <Label Text="{Binding TypeLetter}"
                                                   TextColor="#37474f"
                                                   FontSize="24"
                                                   VerticalTextAlignment="Center"
                                                   HorizontalTextAlignment="Center"/>
                                        </Frame>
                                        <StackLayout Padding="10">
                                            <Label Text="{Binding Name}"
                                               TextColor="Black"
                                               FontSize="24"/>
                                            <StackLayout Orientation="Horizontal">
                                                <Image Source="calendarIcon.png"
                                                       WidthRequest="12"
                                                       HeightRequest="12"/>
                                                <Label Text="{Binding Date}"
                                                       FontSize="12"
                                                       TextColor="Gray"/>
                                            </StackLayout>
                                        </StackLayout>
                                    </StackLayout>
                                </Frame>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </StackLayout>

If you have little rows in Collectionview, you can set a value to collectionView.HeightRequest . when item increase, the height will increase as well.

I create a property called.RowHeigth. If I add item in the CollectionView(with AddCommand), RowHeigth will increase.

<StackLayout>
        <CollectionView
            x:Name="assessmentsCollectionView"
            BackgroundColor="Blue"
            HeightRequest="{Binding rowHeigth}"
            ItemsSource="{Binding letters}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Padding="5" Spacing="10">
                        <Frame
                            Padding="0"
                            CornerRadius="5"
                            HorizontalOptions="FillAndExpand"
                            VerticalOptions="FillAndExpand">
                            <StackLayout Orientation="Horizontal">
                                <Frame
                                    Padding="5"
                                    CornerRadius="0"
                                    WidthRequest="50">
                                    <Label
                                        FontSize="24"
                                        HorizontalTextAlignment="Center"
                                        Text="{Binding TypeLetter}"
                                        TextColor="#37474f"
                                        VerticalTextAlignment="Center" />
                                </Frame>
                                <StackLayout Padding="10">
                                    <Label
                                        FontSize="24"
                                        Text="{Binding Name}"
                                        TextColor="Black" />
                                    <StackLayout Orientation="Horizontal">
                                        <Image
                                            HeightRequest="12"
                                            Source="c1.png"
                                            WidthRequest="12" />
                                        <Label
                                            FontSize="12"
                                            Text="{Binding Date}"
                                            TextColor="Gray" />
                                    </StackLayout>
                                </StackLayout>
                            </StackLayout>
                        </Frame>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <Button
            x:Name="btn1"
            Command="{Binding AddCommand}"
            Text="btn1" />
    </StackLayout>

 public partial class Page4 : ContentPage
{
    
    public Page4()
    {
        InitializeComponent();

        this.BindingContext = new letterviewmodel(); ;
    }
}
public class letterviewmodel: INotifyPropertyChanged
{
    public ObservableCollection<lettermodel> letters { get; set; }
    private int _rowHeigth;
    public int rowHeigth
    {
        get { return _rowHeigth; }
        set
        {
            _rowHeigth = value;
            RaisePropertyChanged("rowHeigth");
        }
    }
    public ICommand AddCommand { protected set; get; }
    public letterviewmodel()
    {
        letters = new ObservableCollection<lettermodel>()
        {
            new lettermodel(){TypeLetter="A",Name="letter 1",Date="2021-01-01"},
            new lettermodel(){TypeLetter="B",Name="letter 2",Date="2021-01-01"},
            new lettermodel(){TypeLetter="C",Name="letter 3",Date="2021-01-01"}

        };
        rowHeigth = letters.Count * 100 ;

        AddCommand = new Command<lettermodel>(async (key) => {
            letters.Add(new lettermodel() { TypeLetter = "D", Name = "test letter ", Date = "2021-01-01" });
            rowHeigth = letters.Count * 100 ;
        });
    }
    
    public event PropertyChangedEventHandler PropertyChanged;       
    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
public class lettermodel
{
    public string TypeLetter { get; set; }
    public string Name { get; set; }
    public string Date { get; set; }
}

Don't forget toimplement INotifyPropertyChanged interface, to inotify data update.

I changed CollectionView to FlexLayout with BindableLayout.ItemsSource and BindableLayout.ItemTemplate What was previously

<CollectionView.ItemTemplate>
                    <DataTemplate>
                        ...
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

What was done

 <FlexLayout Direction="Column"
                         x:Name="MessagesList"
                         AutomationId="MessagesList"
                         BindableLayout.ItemsSource="{Binding Messages}" >
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            ...
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </FlexLayout>

For me works well, no need to set Height for item or FlexLayout, all are dynamic

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM