Вложенные представления и отображение коллекций (с Visual Studio 2019, Xamarin XPlatform Android)

#android #xaml #xamarin.forms #collectionview

#Android #xaml #xamarin.forms #представление коллекций

Вопрос:

  1. Вложенные представления коллекций с прокруткой один внутри другого: поддерживается ли это официально?
  2. Проблема с отображением этих коллекций

Смотрите Ниже мою модель данных и код XAML (у меня нет сайта для размещения результирующего изображения экрана)

 namespace Notes.Models
{
    public class Note
    {
        public enum NoteStatus { suspended, alive }

        public string       Description { get; set; }
        public NoteStatus   Status { get; set; }
    }

    public class NotesContainer
    {
        public string                       Name { get; set; }
        public DateTime                     LastModified { get; set; }
        public ObservableCollection<Note>   ListOfNotes { get; set; }
    }
}
  
   <CollectionView x:Name="notesContainers" SelectionMode="Single" EmptyView="No items currently exist !">
    <CollectionView.ItemTemplate>
      <DataTemplate>
        <Frame BorderColor="Red" BackgroundColor="Beige" CornerRadius="3" HasShadow="False" Padding="5">
          <StackLayout BackgroundColor="Aqua" Padding="5">
            <Grid>
              <Grid.RowDefinitions><RowDefinition Height="auto"/><RowDefinition Height="auto"/></Grid.RowDefinitions>
              <Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions>
              <Label Grid.RowSpan="2" Text="{Binding Name}" VerticalTextAlignment="Center" FontSize="Large"/>
              <Label Grid.Row="0" Grid.Column="1" Text="{Binding LastModified, StringFormat='{0:dddd dd}'}" HorizontalTextAlignment="End"/>
              <Label Grid.Row="1" Grid.Column="1" Text="{Binding LastModified, StringFormat='{0:MMMM yyyy}'}" HorizontalTextAlignment="End"/>
            </Grid>
            <StackLayout BackgroundColor="BlueViolet" Padding="10">
              <CollectionView ItemsSource="{Binding ListOfNotes}" SelectionMode="Single" EmptyView="No items currently exist !">
                <CollectionView.ItemTemplate>
                  <DataTemplate>
            <StackLayout BackgroundColor="Coral" Padding="0,3">
                    <Frame BorderColor="Blue" BackgroundColor="LightBlue" CornerRadius="3" HasShadow="False" Padding="5">
                      <StackLayout Orientation="Horizontal">
                        <Label Text="{Binding Description}" HorizontalOptions="Start" VerticalTextAlignment="Center"/>
                        <Label Text="{Binding Status}" HorizontalOptions="EndAndExpand" VerticalTextAlignment="Center" HorizontalTextAlignment="End"/>
                      </StackLayout>
                    </Frame>
             </StackLayout>
                 </DataTemplate>
                </CollectionView.ItemTemplate>
              </CollectionView>
            </StackLayout>
          </StackLayout>
        </Frame>
      </DataTemplate>
    </CollectionView.ItemTemplate>
  </CollectionView>
  

снимок внешних и внутренних представлений коллекций:

введите описание изображения здесь

Я выделил цвета, чтобы лучше видеть, что макеты не сжаты.

Вопросы: (Я пробовал несколько конфигураций, но без решения)

  1. как я могу уменьшить StackLayouts до его содержимого?
  2. почему StackLayouts увеличивают размер экрана?

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

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

2. Источник элементов внешнего представления коллекции задается в коде с помощью x:Name notesContainers, как показано в XAML. Данные отображаются ПРАВИЛЬНО. Проблема в том, что фреймы и / или стековые описания не сжимаются до их содержимого. Каждый элемент расширяется по экрану и больше.

3. рассматривали ли вы возможность использования группировки ListView, ваши потребности выглядят как два списка, один родительский, а другой дочерний. см . to:learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface /…

4. Я сначала посмотрел на ListView, но на форумах говорят, что вложенный ListView с вложенной прокруткой создает проблемы. Поэтому я надеялся, что новый CollectionView будет принимать вложенные. Это было бы возможно, поскольку я вижу, что многие веб-страницы прокручиваются с внутренней прокруткой зон кода на самой странице прокрутки! Однако я рассмотрю возможности макетов в DataTemplates и заголовки групп в ListView.

5. да, вам нужно только отобразить данные второго списка в listview, чтобы группировка listview могла этого достичь

Ответ №1:

Вместо использования CollectionView следует использовать StackLayout с BindableLayout . У меня только что была такая же проблема, и, наконец, я решил ее с помощью BindableLayout внутри StackLayout следующим образом:

введите описание изображения здесь

Чтобы дать лучшее представление, у меня есть некоторый список объектов внутри родительского элемента. Что-то вроде этого:

 Customers (Items in the code)
--- Products
------- Batches
-----------Series
  

Итак, у меня был список клиентов, который содержит список продуктов, где каждый из них содержит список партий, и, наконец, у них есть список серий.

 <ScrollView>
    <StackLayout BindableLayout.ItemsSource="{Binding Items}">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">

                    <StackLayout x:DataType="ms:Customer" Orientation="Vertical">

                        <StackLayout BindableLayout.ItemsSource="{Binding Products}">
                            <BindableLayout.ItemTemplate>
                                <DataTemplate>

                                    <Frame CornerRadius="10" Margin="5, 5, 5, 5" HasShadow="True" BackgroundColor="#5ac8fa">
                                        <StackLayout>

                                            <StackLayout x:DataType="ms:Product" Orientation="Vertical">
                                                <Label Text="{Binding Name}" FontAttributes="Bold" FontSize="Caption" />
                                                <Label Text="{Binding ProductCode}" FontAttributes="Italic" FontSize="Micro" />

                                                <StackLayout BindableLayout.ItemsSource="{Binding Batches}">
                                                    <BindableLayout.ItemTemplate>
                                                        <DataTemplate>
                                                            <StackLayout x:DataType="ms:Batch" Orientation="Vertical" HorizontalOptions="FillAndExpand">

                                                                <Grid Margin="0,10,0,0">
                                                                    <Grid.ColumnDefinitions>
                                                                        <ColumnDefinition Width="2*" />
                                                                        <ColumnDefinition Width="1*" />
                                                                    </Grid.ColumnDefinitions>
                                                                    <Label Grid.Column="0" Text="{Binding Code}" FontAttributes="Bold" FontSize="Caption" />
                                                                    <Label Grid.Column="1" Text="{Binding ExpiredDateFormated}" FontAttributes="Italic" HorizontalTextAlignment="End" FontSize="Micro" />
                                                                </Grid>

                                                                <StackLayout BindableLayout.ItemsSource="{Binding Serials}">
                                                                    <BindableLayout.ItemTemplate>
                                                                        <DataTemplate>
                                                                            <StackLayout x:DataType="ms:Serial" Orientation="Vertical" HorizontalOptions="FillAndExpand">
                                                                                <Frame CornerRadius="10" HasShadow="True">

                                                                                    <StackLayout>
                                                                                        <Label Text="{Binding SerialCode}" FontAttributes="Bold" FontSize="Micro" />
                                                                                    </StackLayout>
                                                                                    <Frame.GestureRecognizers>
                                                                                        <TapGestureRecognizer 
                                                                                                            NumberOfTapsRequired="1" 
                                                                                                            Command="{Binding Source={RelativeSource AncestorType={x:Type vm:SearchSerialsByLocationViewModel}}, Path=SerialTappedCommand}" 
                                                                                                            CommandParameter="{Binding .}" />
                                                                                    </Frame.GestureRecognizers>
                                                                                </Frame>
                                                                            </StackLayout>
                                                                        </DataTemplate>
                                                                    </BindableLayout.ItemTemplate>
                                                                </StackLayout>

                                                            </StackLayout>
                                                        </DataTemplate>
                                                    </BindableLayout.ItemTemplate>
                                                </StackLayout>

                                            </StackLayout>

                                        </StackLayout>
                                    </Frame>

                                </DataTemplate>
                            </BindableLayout.ItemTemplate>
                        </StackLayout>

                    </StackLayout>
                </StackLayout>
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </StackLayout>
</ScrollView>
  

Это работает действительно хорошо.

введите описание изображения здесь

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

1. Чем вы очень довольны. Я никогда не думал о вашем решении. Я попробую.

2. При попытке использования этого решения я получил сообщение об ошибке «Свойство’DataTemplateContent’ установлено более одного раза».

3. Большое спасибо! Избавил меня от большой головной боли, пытаясь реализовать аналогичную функциональность!

Ответ №2:

Вложенные представления коллекций с прокруткой друг внутри друга: поддерживается ли это официально?

Насколько мне известно, вложенные CollectionViews поддерживаются не всеми платформами, поскольку в них есть прокрутка, а вложенные ScrollViews — широко известная плохая практика.

Проблема с отображением этих коллекций

Я не смог понять, что именно вы здесь имели в виду, но если бы вы могли уточнить, возможно, я смог бы вам помочь.

Как я могу уменьшить StackLayouts его содержимое?

Установка значения Spacing 0 была бы хорошим началом!

Я ожидаю, что StackLayouts не будут превышать размер экрана, как в приведенном выше коде, и несколько данных

Это то, что ваш StackLayout занимает весь экран? (Тот, который находится в ItemTemplate ?)

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

1. 1. И 2. Как я могу без вложенности отображать следующее: каждый внешний элемент с его внутренними элементами с отступом под ним? и сразу после следующего внешнего… без длинного пустого экрана перед каждым внешним элементом (как у меня сейчас)? 3. Интервал = «0» не работает (всегда длинная пустая цветовая зона фона между внешними элементами) 4. Да, первый StackLayout

2. Загрузите изображение, которое описывает, может быть, это облегчит мне задачу!

3. Я добавил изображение экрана в свое первое сообщение выше

4. Я хотел, чтобы вы добавили то, чего вы хотите достичь, а не то, что у вас есть!!

5. Я хочу, чтобы первое StackLayout с backgroundColor=»Aqua» корректировало свой размер в соответствии с его содержимым, и чтобы второе StackLayout во втором CollectionView с backgroundColor =»BlueViolet» также изменяло размеры (вокруг макетов Repa и Oeufs на изображении) Надеюсь, это поможет.

Ответ №3:

Я просто занимался этим сам и нашел это решение: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/grouping

Короче говоря: идея состоит в том, чтобы реструктурировать ваши данные таким образом, чтобы родительский элемент был a List<child> с дополнительными свойствами, включенными IsGrouping в вашем CollectionView , структурировать родительский элемент как the CollectionView.GroupHeaderTemplate , а дочерний как the CollectionView.ItemTemplate .

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

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