I have a ListView in .NET MAUI, I want it so that when an item in the ListView is clicked, it scales up and then back down. I've managed to get the ViewCell for each templated item and subsequently the Grid view within (which is what I want to scale), but when I change the scale, nothing happens. I imagine that, for performance reasons, the ListView only renders items when they're added and does not render any changes made afterwards. Is there any way to change this, or to otherwise achieve the effect I want?
Here's the XAML for the ListView and its DataTemplate:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="GakugoMAUI.Views.LessonListView">
<ContentView.Resources>
<ResourceDictionary>
<DataTemplate x:Key="LessonButton">
<ViewCell>
<Grid Scale="1">
<BoxView HorizontalOptions="Fill"
VerticalOptions="Fill"
CornerRadius="10"
Color="{AppThemeBinding Light={StaticResource Gray100}, Dark={StaticResource Gray750}}"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image VerticalOptions="Fill"
Margin="15,0,0,0"
Scale="1.1"
Grid.Column="0">
<Image.Source>
<FontImageSource Glyph="{Binding Glyph}"
FontFamily="{Binding GlyphFontFamily}"
Color="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource Secondary}}"/>
</Image.Source>
</Image>
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Label Text="{Binding TitleText}"
FontSize="16"
Grid.Row="1"/>
<Label Text="{Binding SubtitleText}"
FontSize="12"
FontAttributes="Italic"
Grid.Row="2"/>
</Grid>
</Grid>
</Grid>
</ViewCell>
</DataTemplate>
</ResourceDictionary>
</ContentView.Resources>
<Grid>
<ListView x:Name="lessonsList"
ItemsSource="{Binding LessonButtons}"
ItemTemplate="{StaticResource LessonButton}"
ItemTapped="LessonButton_Clicked"
Margin="10"
Grid.Row="3"/>
</Grid>
</ContentView>
And here's the method for when an item is clicked:
public async void LessonButton_Clicked(object sender, ItemTappedEventArgs e)
{
if (sender is ListView list)
{
var cells = list.GetVisualTreeDescendants().Where(x => x.GetType() == typeof(ViewCell));
Grid currentItem = (Grid)((ViewCell)cells.ElementAt(e.ItemIndex)).View;
await currentItem.ScaleTo(1.5);
await currentItem.ScaleTo(1);
}
}
You can try to add the TapGestureRecognizer
for the Grid:
<DataTemplate x:Key="LessonButton">
<ViewCell>
<Grid Scale="1">
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Grid.GestureRecognizers>
And in the code behind:
private async void TapGestureRecognizer_Tapped(object sender, TappedEventArgs e)
{
await (sender as Grid).ScaleTo(1.5);
await (sender as Grid).ScaleTo(1.0);
}