Reputation: 159
I am fairly new to MAUI Apps and what i have is a CarouselView bound to a collection of students. Everything is working fine, however I have an issue which appears to be widespread - I have a Next and Previous button which I want to use to navigate from one item in the carousel to the next.
The Previous button works fine, however the Next button doesn't behave as expected. If I have, for example, 3 students in my collection, I cannot smoothly navigate from Student 1 (position 0) to Student 2 (position 1).
I have to click the next button twice and it's only on the 3rd click that it finally moves to student 2. It keeps resetting back to student 1. I monitored the behavior in Debug mode and I can see that the current Item in the preview does indeed change when I debug the NextButton_Clicked method, but as soon as the debug exits the method, the CurrentItem resets back to student 1 (position 0). As I mentioned, my Students collection is working fine and the data is as expected and I do not have any other (visible) triggers that may be overriding the CurrentItem change. For reference, my methods in the code-behind are below:
private void NextButton_Clicked(object sender, EventArgs e)
{
if (StudentCarousel.ItemsSource is IList<Student> students)
{
int studentCount = students.Count;
int nextPosition = (CurrentPosition + 1) % studentCount;
Debug.WriteLine($"NextButton_Clicked: Setting Position to {nextPosition}");
// Update Position before CurrentItem
CurrentPosition = nextPosition;
StudentCarousel_CurrentItem = students[nextPosition];
}
}
private void StudentCarousel_PositionChanged(object sender, PositionChangedEventArgs e)
{
Debug.WriteLine($"PositionChanged Event: New Position = {e.CurrentPosition}");
}
private void CarouselView_CurrentItemChanged(System.Object sender, Microsoft.Maui.Controls.CurrentItemChangedEventArgs e)
{
if (e.CurrentItem is Student currentStudent)
{
CurrentItem = currentStudent;
}
}
I also have the code below:
public ObservableCollection<Student> Students { get; set; } = new ObservableCollection<Student>();
private int _currentPosition;
public int CurrentPosition
{
get => _currentPosition;
set
{
if (_currentPosition != value)
{
_currentPosition = value;
OnPropertyChanged(nameof(CurrentPosition));
Debug.WriteLine($"CurrentPosition set to: {_currentPosition}");
}
}
}
private Student _studentCarousel_CurrentItem;
public Student StudentCarousel_CurrentItem
{
get => _studentCarousel_CurrentItem;
set
{
if (_studentCarousel_CurrentItem != value)
{
_studentCarousel_CurrentItem = value;
OnPropertyChanged(nameof(StudentCarousel_CurrentItem));
}
}
}
Below is the .xaml code:
<Frame Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1" Margin="5" BorderColor="Gray" BackgroundColor="White" HasShadow="True" HeightRequest="250" WidthRequest="300"
HorizontalOptions="Center" VerticalOptions="Center">
<StackLayout Orientation="Vertical" HorizontalOptions="Center" VerticalOptions="Center" Padding="10">
<!-- CarouselView -->
<RefreshView>
<CarouselView x:Name="StudentCarousel" ItemsSource="{Binding Students}" Loop="True"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
HeightRequest="250" WidthRequest="300" IndicatorView="CarouselIndicator" IsScrollAnimated="True" CurrentItem="{Binding StudentCarousel_CurrentItem, Mode=TwoWay}" CurrentItemChanged="CarouselView_CurrentItemChanged" Position="{Binding CurrentPosition, Mode=TwoWay}" PositionChanged="StudentCarousel_PositionChanged" >
<CarouselView.ItemTemplate>
<DataTemplate>
<Grid Padding="10" RowSpacing="5" ColumnSpacing="10" HorizontalOptions="Center" VerticalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Image -->
<Image Source="student_icon.png" Grid.Row="0" Grid.Column="0" HeightRequest="40" WidthRequest="40" HorizontalOptions="Center" />
<!-- Label: Student Info -->
<Label Text="Student Info" Grid.Row="1" Grid.Column="0" FontAttributes="Bold" FontSize="Small" HorizontalOptions="Center" VerticalOptions="Center" />
<!-- Label: Full Name -->
<Label Grid.Row="2" Grid.Column="0" HorizontalOptions="Start" VerticalOptions="Center">
<Label.FormattedText>
<FormattedString>
<Span Text="FullName: " FontAttributes="Bold" />
<Span Text="{Binding FullNameWithMiddleName}" />
</FormattedString>
</Label.FormattedText>
</Label>
</Grid>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</RefreshView>
<!-- Navigation Buttons -->
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" Margin="0,10,0,0">
<Button x:Name="PreviousButton" Text="Previous" Clicked="PreviousButton_Clicked" />
<Button x:Name="NextButton" Text="Next" Clicked="NextButton_Clicked" Margin="10,0,0,0" />
</StackLayout>
</StackLayout>
</Frame>
I am completely stuck and not sure where I am going wrong. Any advice is appreciated.
Upvotes: 2
Views: 96
Reputation: 224
Here is my solution.
I remove the currentItem
and change it to Student_CurrentItem
.
private void CarouselView_CurrentItemChanged(System.Object sender, Microsoft.Maui.Controls.CurrentItemChangedEventArgs e)
{
if (e.CurrentItem is Student currentStudent)
{
Student_CurrentItem = currentStudent;
}
}
Upvotes: 1