Xamarin - CollectionView VerticalItemSpacing not working

Viewed 4928

I am clueless what might be wrong, I've tested several code variants and none of them worked. I've also tried variant with Frame and StackLayout.

<ScrollView VerticalOptions="StartAndExpand" Orientation="Vertical">
    <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <CollectionView Grid.Row="0" x:Name="StockCards_CollectionView" ItemsSource="{Binding lc_ReleaseBill.Items}" SelectionChangedCommand="{Binding OnCollectionViewSelectionChanged}" EmptyView="List is empty." SelectionMode="Single"  SelectedItem="{Binding SelectedStockCard, Mode=TwoWay}">
            <CollectionView.ItemsLayout>
                <GridItemsLayout Orientation="Vertical"  VerticalItemSpacing="20"/>
            </CollectionView.ItemsLayout>
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                            <Label Grid.Row="0" Grid.Column="0"  Text="{Binding Name}" FontAttributes="Bold" VerticalOptions="Start" TextColor="White"/>

                            <Label Grid.Row="1" Grid.Column="0"  Text="{Binding Unit}" FontAttributes="Italic"  VerticalOptions="Start" TextColor="White"/>

                            <Label Grid.Row="0" Grid.Column="1"  Text="{Binding Price_WithVAT_Unit}" FontAttributes="Bold"  HorizontalOptions="End" FontSize="19" TextColor="#00c8df"/>

                            <Label Grid.Row="1" Grid.Column="1"  Text="{Binding Amount}" FontAttributes="Bold"  HorizontalOptions="End" TextColor="White"/>
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>
</ScrollView> 

Running on Xamarin.Forms 4.5.0.356 and the same result was on 4.4.0.991640.

3 Answers

I fixed it by setting Collection View Item Spacing from code, which is not ideal but its better than setting margin on Grid inside of Collection View.

CollectionView.ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
    {
       ItemSpacing = 20
    };

You could try adding Margin to the DataTemplate Content inside a ContentView

<CollectionView Grid.Row="0" x:Name="StockCards_CollectionView" ItemsSource="{Binding lc_ReleaseBill.Items}" SelectionChangedCommand="{Binding OnCollectionViewSelectionChanged}" EmptyView="List is empty." SelectionMode="Single"  SelectedItem="{Binding SelectedStockCard, Mode=TwoWay}">
    <CollectionView.ItemsLayout>
        <GridItemsLayout Orientation="Vertical"/>
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <ContentView>
                <Grid Margin="0,0,0,20">
                   ...
                </Grid>
            <(ContentView>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Also, you should try using ItemSpacing="20" instead of VerticalItemSpacing

Edit: Since the ItemSpacing does work, but only after it has some more items in it enough for the scroll back and foward, i would try this technique:

Set the IsVisible property to false, and after your Collection has data, set it to true:

<CollectionView IsVisible="{Binding CollectionHasData}" Grid.Row="0" x:Name="StockCards_CollectionView" ItemsSource="{Binding lc_ReleaseBill.Items}" SelectionChangedCommand="{Binding OnCollectionViewSelectionChanged}" EmptyView="List is empty." SelectionMode="Single"  SelectedItem="{Binding SelectedStockCard, Mode=TwoWay}">

private bool _collectionHasData;

public bool CollectionHasData
{
    get => _item;
    set { _collectionHasData = value; }
}

...

lc_ReleaseBill.Items = Data;
CollectionHasData = true;

I don't know how you fetch your data, if you set it or the object already has the data, but the point is, when your Items has some values, set the bool to true

Margin and spacing have do not get updated for a new item added, the only way they get updated is if they are scrolled off then back on the screen.

Related