In my .NET MAUI App, I have the following ContentPage
.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:loc="clr-namespace:LocalizationResourceManager.Maui;assembly=LocalizationResourceManager.Maui"
xmlns:viewModels="clr-namespace:OptimizerApp.ViewModels"
x:DataType="viewModels:ManageItemsHelpPageViewModel"
x:Class="OptimizerApp.Pages.HelpPages.ManageItemsHelpPage"
Title="{loc:Translate HelpTopic_ManageItems}"
x:Name="This">
<ContentPage.BindingContext>
<viewModels:ManageItemsHelpPageViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="BorderStyleView" TargetType="Border">
<Setter Property="Background" Value="{StaticResource White}" />
<Setter Property="StrokeShape" Value="RoundRectangle 10, 10, 10, 10" />
<Setter Property="Margin" Value="15" />
<Setter Property="Opacity" Value="0.6" />
<Setter Property="Padding" Value="0" />
</Style>
<Style TargetType="Label">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<Grid>
<Image ZIndex="1" Source="help_page.jpg" Aspect="AspectFill" VerticalOptions="End"/>
<Grid ZIndex="2">
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="White" Offset="0.0" />
<GradientStop Color="Transparent" Offset="1.0" />
</LinearGradientBrush>
</Grid.Background>
</Grid>
<Grid ZIndex="3">
<Border x:Name="HelpPageBorder" VerticalOptions="FillAndExpand" Style="{StaticResource BorderStyleView}" SizeChanged="HelpPageBorder_SizeChanged"/>
<Grid RowDefinitions="*, Auto" BackgroundColor="Transparent" Padding="15">
<ScrollView Margin="0,0,0,25" Orientation="Vertical" HeightRequest="{Binding Source={x:Reference This}, Path=CarouselViewItemHeight}" VerticalOptions="Start" HorizontalOptions="Fill">
<CarouselView x:Name="carouselView" Background="Transparent" ItemsSource="{Binding Items}" Loop="False" IsBounceEnabled="False" IndicatorView="indicatorView" VerticalOptions="Start">
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" SnapPointsType="MandatorySingle" SnapPointsAlignment="Center" />
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate x:DataType="viewModels:CarouselItem">
<Grid x:Name="carouselViewGrid" RowDefinitions="0.4*, 0.6*" ColumnDefinitions="*" Background="Yellow" VerticalOptions="Fill" HorizontalOptions="Fill">
<Frame Grid.Row="0" CornerRadius="20" HasShadow="False" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Margin="20">
<Image Source="{Binding Image}" Aspect="AspectFit" IsAnimationPlaying="True" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</Frame>
<StackLayout Grid.Row="1" Padding="0,0,0,25" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<Label Text="{Binding Title}" FontAttributes="Bold" FontSize="22" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" />
<Label Text="{Binding Description}" FontSize="16" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Margin="10" />
</StackLayout>
</Grid>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</ScrollView>
<IndicatorView x:Name="indicatorView" Grid.Row="1" IndicatorColor="LightGray" SelectedIndicatorColor="DarkGray" IndicatorsShape="Circle" HorizontalOptions="Center" VerticalOptions="End" Margin="0, 0, 0, 25" />
</Grid>
</Grid>
</Grid>
</ContentPage>
namespace OptimizerApp.Pages.HelpPages
{
public partial class ManageItemsHelpPage : ContentPage
{
public static readonly BindableProperty CarouselViewItemHeightProperty = BindableProperty.Create(nameof(CarouselViewItemHeight), typeof(double), typeof(ManageItemsHelpPage), 0.0);
public static readonly BindableProperty CarouselViewItemWidthProperty = BindableProperty.Create(nameof(CarouselViewItemWidth), typeof(double), typeof(ManageItemsHelpPage), 0.0);
public double CarouselViewItemHeight
{
get => (double)GetValue(CarouselViewItemHeightProperty);
set => SetValue(CarouselViewItemHeightProperty, value);
}
public double CarouselViewItemWidth
{
get => (double)GetValue(CarouselViewItemWidthProperty);
set => SetValue(CarouselViewItemWidthProperty, value);
}
public ManageItemsHelpPage()
{
InitializeComponent();
}
private void HelpPageBorder_SizeChanged(object sender, EventArgs e)
{
if (HelpPageBorder.Height > 0)
{
CarouselViewItemHeight = HelpPageBorder.Height - 180;
}
if (HelpPageBorder.Width > 0)
{
CarouselViewItemWidth = HelpPageBorder.Width;
}
}
}
}
As can be seen, the CarouselView
should be scrolled horizontally, but when I scroll my ScrollView
, I can see the 2nd Image which is bound to it, shows somewhere underneath the 1st Image:
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" SnapPointsType="MandatorySingle" SnapPointsAlignment="Center" />
</CarouselView.ItemsLayout>
The most annoying part is, that yellow part (the Grid
) does not really just Fill
horizontally, but it also streches the ScrollView
obviously horizontally.
I tried different things with layouts and also explicit WidthRequest
based on the outside Border
, but couldn’t get what I wanted.
What I wanted to achieve was that I have the content of one CarouselView
-Page scrollable if the space is not sufficient (e.g. in Landscape orientation). The Width
whould be restricted to the width of the parent Border
. The IndicatorView
should be visible at the bottom. Therefore, I placed the ScrollView
inside the Grid
. And as I mentioned, I also was wondering why it does not scroll vertically anymore.
What am I doing wrong and how can I achieve this here?