Reputation: 828
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).
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
Upvotes: 3
Views: 3439
Reputation: 51
@doss-bilure The answer is correct and solves this problem.
Just a little note: if you edit collection CarouselView
, it automatically changes Position
, so it matches the previously selected item. If you want to add an item without this change, you have to edit both Position
and CurrentItem
Upvotes: 2
Reputation: 51
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.
Upvotes: 5