.Net MAUI Binding for ListView ItemSelected

Gavin Beard 21 Reputation points
2022-12-30T18:55:05.027+00:00

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

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,596 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,012 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 76,551 Reputation points Microsoft Vendor
    2023-01-02T01:51:28.997+00:00

    Hello,

    error "No property, BindableProperty, or event found for "ItemSelected", or mismatching type between value and property"

    ItemSelected is an event, you cannot add the binding property in the xaml. You add the SelectedItem in the listview, so you do not need to add ItemSelected event, just remove it.

    Here is a document about how to use ItemSelected event in the listview.

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. Gavin Beard 21 Reputation points
    2023-01-03T09:08:24.627+00:00

    Thank you very much, I've ended up moving onto CollectionView instead of ListView due to some issues with ListView on IOS (such as cells going blank when app re-entering foreground) and this has brought its own bunch on issues I will post shortly

    ~Thanks for your help Leon

    0 comments No comments

  2. Cliff Choongo 0 Reputation points
    2024-09-10T09:50:35.2+00:00

    The reason why you are getting that error is that Item selected is an event not a bindable property as such it does not support bindings of any kind.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.