All skills
davidortinau avatar

/maui-collectionview

@73e29ff

Guidance for implementing CollectionView in .NET MAUI apps — data display, layouts (list & grid), selection, grouping, scrolling, empty views, templates, incremental loading, swipe actions, and pull-to-refresh. USE FOR: "CollectionView", "list view", "grid layout", "data template", "item template", "grouping", "pull to refresh", "incremental loading", "swipe actions", "empty view", "selection mode", "scroll to item". DO NOT USE FOR: simple static layouts (use maui-data-binding), map pin lists (use maui-maps), or table-based data entry forms.

Use this Skill: https://skilld.dev/gh/davidortinau/maui-skills/maui-collectionview

This session only. Nothing lands on disk.

referencescollectionview-api.md

≈1.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

CollectionView API Reference

Layouts

Set ItemsLayout to control arrangement. Default is VerticalList.

Layout XAML value
Vertical list VerticalList (default)
Horizontal list HorizontalList
Vertical grid GridItemsLayout with Orientation="Vertical"
Horizontal grid GridItemsLayout with Orientation="Horizontal"

Grid layout

<CollectionView ItemsSource="{Binding Items}">
    <CollectionView.ItemsLayout>
        <GridItemsLayout Orientation="Vertical"
                         Span="2"
                         VerticalItemSpacing="8"
                         HorizontalItemSpacing="8" />
    </CollectionView.ItemsLayout>
</CollectionView>

Horizontal list

<CollectionView ItemsSource="{Binding Items}"
                ItemsLayout="HorizontalList" />

ItemSizingStrategy

Controls how items are measured. Set on ItemsLayout.

Value Behavior
MeasureAllItems Measures every item individually (default). Accurate but slower for heterogeneous sizes.
MeasureFirstItem Measures only the first item and applies that size to all. Much faster for uniform items.
<CollectionView.ItemsLayout>
    <LinearItemsLayout Orientation="Vertical"
                       ItemSizingStrategy="MeasureFirstItem" />
</CollectionView.ItemsLayout>

ItemSpacing

Use ItemSpacing on LinearItemsLayout or VerticalItemSpacing / HorizontalItemSpacing on GridItemsLayout:

<CollectionView.ItemsLayout>
    <LinearItemsLayout Orientation="Vertical" ItemSpacing="8" />
</CollectionView.ItemsLayout>

Headers and Footers

Supports string, view, or templated:

<!-- Simple string -->
<CollectionView Header="My Items" Footer="End of list" />

<!-- Custom view -->
<CollectionView ItemsSource="{Binding Items}">
    <CollectionView.Header>
        <Label Text="Header" FontAttributes="Bold" Padding="8" />
    </CollectionView.Header>
    <CollectionView.Footer>
        <Label Text="Footer" FontAttributes="Italic" Padding="8" />
    </CollectionView.Footer>
</CollectionView>

Use HeaderTemplate / FooterTemplate when headers/footers are data-bound.

Selection

Selection mode

Mode Property to bind Binding mode
None — —
Single SelectedItem TwoWay
Multiple SelectedItems OneWay
<CollectionView ItemsSource="{Binding Items}"
                SelectionMode="Single"
                SelectedItem="{Binding CurrentItem, Mode=TwoWay}"
                SelectionChangedCommand="{Binding ItemSelectedCommand}" />

For Multiple selection, bind SelectedItems (type IList<object>):

<CollectionView SelectionMode="Multiple"
                SelectedItems="{Binding ChosenItems, Mode=OneWay}" />

Selected visual state

Highlight selected items using VisualStateManager:

<CollectionView.ItemTemplate>
    <DataTemplate x:DataType="models:Item">
        <Grid Padding="8">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup Name="CommonStates">
                    <VisualState Name="Normal">
                        <VisualState.Setters>
                            <Setter Property="BackgroundColor" Value="Transparent" />
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState Name="Selected">
                        <VisualState.Setters>
                            <Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Label Text="{Binding Name}" />
        </Grid>
    </DataTemplate>
</CollectionView.ItemTemplate>

Grouping

  1. Create a group class inheriting from List<T>:
public class AnimalGroup : List<Animal>
{
    public string Name { get; }
    public AnimalGroup(string name, List<Animal> animals) : base(animals)
    {
        Name = name;
    }
}
  1. Bind to ObservableCollection<AnimalGroup> and set IsGrouped="True":
<CollectionView ItemsSource="{Binding AnimalGroups}"
                IsGrouped="True">
    <CollectionView.GroupHeaderTemplate>
        <DataTemplate x:DataType="models:AnimalGroup">
            <Label Text="{Binding Name}"
                   FontAttributes="Bold"
                   BackgroundColor="{StaticResource Gray100}"
                   Padding="8" />
        </DataTemplate>
    </CollectionView.GroupHeaderTemplate>
    <CollectionView.GroupFooterTemplate>
        <DataTemplate x:DataType="models:AnimalGroup">
            <Label Text="{Binding Count, StringFormat='{0} items'}"
                   FontAttributes="Italic"
                   Padding="4,0" />
        </DataTemplate>
    </CollectionView.GroupFooterTemplate>
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="models:Animal">
            <Label Text="{Binding Name}" Padding="16,4" />
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

EmptyView

Shown when ItemsSource is empty or null.

<!-- Simple string -->
<CollectionView EmptyView="No items found." />

<!-- Custom view — wrap in a ContentView -->
<CollectionView ItemsSource="{Binding SearchResults}">
    <CollectionView.EmptyView>
        <ContentView>
            <VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center">
                <Image Source="empty_state.png" WidthRequest="120" />
                <Label Text="Nothing here yet" HorizontalTextAlignment="Center" />
            </VerticalStackLayout>
        </ContentView>
    </CollectionView.EmptyView>
</CollectionView>

You can also use EmptyViewTemplate with a DataTemplateSelector to swap empty views based on state.

Scrolling

ScrollTo

Programmatically scroll by index or item:

// Scroll to index
collectionView.ScrollTo(index: 10, position: ScrollToPosition.Center, animate: true);

// Scroll to item
collectionView.ScrollTo(item: myItem, position: ScrollToPosition.MakeVisible, animate: true);
ScrollToPosition Behavior
MakeVisible Scrolls just enough to make the item visible
Start Scrolls item to the start of the viewport
Center Scrolls item to the center of the viewport
End Scrolls item to the end of the viewport

Snap points

Control snap behavior after scrolling:

<CollectionView.ItemsLayout>
    <LinearItemsLayout Orientation="Horizontal"
                       SnapPointsType="MandatorySingle"
                       SnapPointsAlignment="Center" />
</CollectionView.ItemsLayout>
  • SnapPointsType: None, Mandatory, MandatorySingle
  • SnapPointsAlignment: Start, Center, End

Source: SKILL.md on GitHub

No alerts15d4 checks · Risk SAFE
  • Gen Agent Trust Hub15d

    No security issues detected. The skill provides legitimate documentation and code snippets for .NET MAUI development.

  • Socket15d

    No alerts

  • Snyk15d

    Risk: LOW · No issues

  • Runlayer7mo

    1 file scanned · No issues

Signed by skilld at 73e29ff. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 6 months ago

README badge

README badge for davidortinau/maui-skills/maui-collectionview