Hi all,
I am trying to bind the ItemSelected of a ListView to a View Model, but am experiencing some issues (due to my own misunderstands around how it all works).
I have view:
<?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:Local="clr-namespace:FireLearn.ViewModels"
x:Class="FireLearn.MainPage"
Title="Categories">
<ContentPage.BindingContext>
<Local:CategoryViewModel/>
</ContentPage.BindingContext>
<NavigationPage.TitleView>
<Label Text="Home"/>
</NavigationPage.TitleView>
<ListView
ItemsSource="{Binding Categories}"
HasUnevenRows="True"
IsPullToRefreshEnabled="True"
IsRefreshing="{Binding ListRefreshing, Mode=OneWay}"
RefreshCommand="{Binding RefreshCommand}"
ItemSelected="{Binding OnItemTappedChanged}"
SelectionMode="Single"
SelectedItem="{Binding SelectedCategory}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<HorizontalStackLayout
Padding="8"
VerticalOptions="Fill"
HorizontalOptions="Fill">
<Image Source="cafs_bubbles.png"
HeightRequest="64"
MaximumWidthRequest="64"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
<VerticalStackLayout
Padding="8"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Label Text="{Binding FormattedName}"
SemanticProperties.HeadingLevel="Level1"
FontSize="Title"
HorizontalOptions="Start"/>
<Label Text="{Binding ItemCount}"
FontSize="Subtitle"/>
<Label Text="{Binding Description}"
HorizontalOptions="Center"
LineBreakMode="WordWrap"
FontSize="Caption"
VerticalOptions="CenterAndExpand"
MaxLines="0"/>
</VerticalStackLayout>
</HorizontalStackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
This is linked to a view model:
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FireLearn.Models;
namespace FireLearn.ViewModels
{
public partial class CategoryViewModel : ObservableObject
{
public ObservableCollection<CategoryModel> categories = new ObservableCollection<CategoryModel>();
public ObservableCollection<CategoryModel> Categories
{
get => categories;
set => SetProperty(ref categories, value);
}
public bool listRefreshing = false;
public bool ListRefreshing
{
get => listRefreshing;
set => SetProperty(ref listRefreshing, value);
}
public CategoryModel selectedCategory = new CategoryModel();
public CategoryModel SelectedCategory
{
get => selectedCategory;
set
{
SetProperty(ref selectedCategory, value);
// Tap(value);
}
}
public RelayCommand RefreshCommand { get; set; }
//public RelayCommand TapCellCommand { get; set; }
public CategoryViewModel()
{
loadFromSource();
RefreshCommand = new RelayCommand(async () =>
{
Debug.WriteLine($"STARTED::{ListRefreshing}");
if (!ListRefreshing)
{
ListRefreshing = true;
try
{
await loadFromSource();
}
finally
{
ListRefreshing = false;
Debug.WriteLine($"DONE::{ListRefreshing}");
}
}
});
}
public async Task loadFromSource()
{
HttpClient httpClient = new()
{
Timeout = new TimeSpan(0, 0, 10)
};
Uri uri = new Uri("https://somewebsite.co.uk/wp-json/wp/v2/categories");
HttpResponseMessage msg = await httpClient.GetAsync(uri);
if (msg.IsSuccessStatusCode)
{
var result = CategoryModel.FromJson(await msg.Content.ReadAsStringAsync());
Categories = new ObservableCollection<CategoryModel>(result);
}
Debug.WriteLine("List Refreshed");
}
public void ListView_ItemSelected(System.Object sender, Microsoft.Maui.Controls.SelectedItemChangedEventArgs e)
{
var x = new ShellNavigationState();
Shell.Current.GoToAsync(nameof(NewPage1),
new Dictionary<string, object>
{
{
nameof(NewPage1),
SelectedCategory
}
});
}
}
}
I get compiler error "No property, BindableProperty, or event found for "ItemSelected", or mismatching type between value and property" and am really unsure of how to resolve. If I let XAML create a new event for me, it adds it in MainPage.Xaml.Cs rather than the VM