Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET MAUI CarouselView changing position is not working without swiping at least once

I am trying to create an onboarding view with CarouselView. I have a position indicator and a button to change the carousel view item. When I press the button, it should display the next item. Alternatively, if I click on the indicator, it should change the item too!

The problem is, without swiping the view at least once or setting the position to zero from the UI (by going to an arbitrary position and pressing the first index from the indicator.), I can't control its position. (Demo in the gif below).

enter image description here

Here is my CaouselView XAML

 <Grid RowDefinitions="*,Auto">
        <CarouselView x:Name="OnBoardingCarouselView"
                      HorizontalOptions="FillAndExpand"
                      VerticalOptions="FillAndExpand"
                      IsBounceEnabled="False"
                      Loop="False" ItemsSource="{Binding IntroScreens}"
                      PositionChangedCommand="{Binding HandlePositionChangedCommand}"
                      PositionChangedCommandParameter="{Binding Source={RelativeSource Self}, Path=Position}"
                      IndicatorView="CarouselIndicator"
                      Position="{Binding CarouselPosition, Mode=TwoWay}">
            <CarouselView.ItemTemplate>
                <DataTemplate x:DataType="models:IntroScreen">
                    <Grid RowDefinitions="60*,40*">
                        <Image Source="{Binding Image}" HeightRequest="200"></Image>
                        <VerticalStackLayout Grid.Row="1">
                            <Label Text="{Binding IntroTitle}"
                                   FontSize="Title"></Label>
                            <Label Text="{Binding IntroDescription}"
                                   FontSize="Body"></Label>
                        </VerticalStackLayout>
                    </Grid>
                </DataTemplate>
            </CarouselView.ItemTemplate>
        </CarouselView>
        <Grid Grid.Row="1" ColumnDefinitions="*,Auto">
            <IndicatorView x:Name="CarouselIndicator" Grid.Column="0"
                           IndicatorsShape="Circle"
                           IndicatorSize="12"
                           IndicatorColor="{StaticResource Secondary}"
                           SelectedIndicatorColor="{StaticResource Primary}"
                           VerticalOptions="Center"></IndicatorView>
            <StackLayout Grid.Column="1">
                <Button x:Name="NextButton" Text="Next" 
                        Command="{Binding HandleNextButtonClickCommand}"
                        IsVisible="{Binding NextButtonVisibility}"></Button>
                <Button x:Name="EnterButton" Text="Enter" 
                        Command="{Binding HandleEnterButtonClickCommand}"
                        IsVisible="{Binding EnterButtonVisibility}"></Button>
            </StackLayout>
        </Grid>

I have tried to set starting position like this, and it is not working -

    public IntroScreenView()
    {
        InitializeComponent();

        // Check if the position preset is working
        OnBoardingCarouselView.Position = 1;
    }

Here is my corresponding view model -

[ObservableObject]
    public partial class IntroScreenViewModel
    {
        [ObservableProperty]
        private int carouselPosition;
        [ObservableProperty]
        private bool nextButtonVisibility;
        [ObservableProperty]
        private bool enterButtonVisibility;
        [ObservableProperty]
        private ObservableCollection<IntroScreen> introScreens;

        public IntroScreenViewModel()
        {
            EnterButtonVisibility = false;
            NextButtonVisibility = true;
            IntroScreens = new ObservableCollection<IntroScreen>
            {
                new()
                {
                    IntroTitle = "Intro Title One",
                    IntroDescription = "Lorem is some time ipsum but ipsum can't be lorem.",
                    Image = "cr_1.svg"
                },
                new()
                {
                    IntroTitle = "Intro Title Two",
                    IntroDescription = "Lorem is some time ipsum but ipsum can't be lorem.",
                    Image = "cr_2.svg"
                },
                new()
                {
                    IntroTitle = "Intro Title Three",
                    IntroDescription = "Lorem is some time ipsum but ipsum can't be lorem.",
                    Image = "cr_3.svg"
                }
            };
            // commenting the following line or setting to any position 
            // does not affect anything
            CarouselPosition = 0;
        }
        [RelayCommand]
        public void HandlePositionChanged(int position)
        {
            // here position variable always gets the correct position
            if (position == IntroScreens.Count - 1)
            {
                EnterButtonVisibility = true;
                NextButtonVisibility = false;
            }
            else
            {
                EnterButtonVisibility = false;
                NextButtonVisibility = true;
            }
        }
        [RelayCommand]
        public void HandleNextButtonClick()
        {
            if (CarouselPosition + 1 < introScreens.Count)
                CarouselPosition++;
        }

        [RelayCommand]
        public void HandleEnterButtonClick()
        {
            Application.Current!.MainPage = new LoginPageView();
        }
    }

Full source code is here https://github.com/MahmudX/Binimoy

like image 804
Mahmudul Hasan Avatar asked Dec 06 '25 17:12

Mahmudul Hasan


1 Answers

I also encountered this problem. After several hours of experiments, I realized that problem is in Loop property.

Setting Loop="True" in CarouselView resolves this problem.

Anyway, it's MAUI bug.

like image 67
Doss Bilure Avatar answered Dec 08 '25 08:12

Doss Bilure



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!