Xamarin.Forms — Настройка высоты CollectionView на минимальный размер для дочерних элементов

#c# #xaml #xamarin #xamarin.forms

#c# #xaml #xamarin #xamarin.forms

Вопрос:

У меня есть CollectionView с несколькими элементами в нем. Я пытаюсь настроить размер CollectionView так, чтобы он был достаточно большим, чтобы вместить всех его дочерних элементов. Прямо сейчас он намного больше, чем количество дочерних элементов, которые у него есть. введите описание изображения здесь

Синий цвет представляет размер CollectionView. Как вы можете видеть, это намного превышает размер его дочерних элементов. Я бы хотел, чтобы он идеально подходил им или, по крайней мере, был ближе к тому же размеру.

У меня нет никаких запросов на высоту ни для одного из элементов на странице, включая CollectionView.

Вот мой код. На данный момент это не особенно красиво, но это незавершенная работа.

 <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>
 

Ответ №1:

Я изменил CollectionView на FlexLayout с помощью BindableLayout.ItemsSource и BindableLayout .ItemTemplate Что было ранее

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

Что было сделано

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

Для меня работает хорошо, нет необходимости устанавливать высоту для элемента или гибкого описания, все они динамические

Комментарии:

1. Мне это нравится… хорошее решение

Ответ №2:

Если у вас мало строк в Collectionview, вы можете задать значение CollectionView .Запрос высоты. при увеличении элемента высота также будет увеличиваться.

Я создаю свойство с именем.Высота. Если я добавлю элемент в CollectionView (с помощью addCommand), высота будет увеличиваться.

 <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; }
}
 

Не забудьте внедрить интерфейс INotifyPropertyChanged, чтобы инициализировать обновление данных.

Комментарии:

1. Это разумный способ сделать это. Мне бы понравилось, если бы было какое-то свойство, которое просто заставляло бы родительские объекты по высоте и / или ширине точно соответствовать его содержимому, но, похоже, этого не существует.

2. @KnightSteele — проблема с обсуждением здесь .