I am trying to create a ListView that supports the pull to refresh feature of ListView.
My XAML is:
<?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>
<ListView
ItemsSource="{Binding Categories}"
ItemSelected="ListView_ItemSelected"
HasUnevenRows="True"
IsPullToRefreshEnabled="True"
IsRefreshing="{Binding ListRefreshing}"
RefreshCommand="{Binding RefreshCommand}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<HorizontalStackLayout
Padding="8">
<Image Source="cafs_bubbles.png"
HeightRequest="64"/>
<VerticalStackLayout
Padding="8">
<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"/>
</VerticalStackLayout>
</HorizontalStackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
and the code behind is:
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using FireLearn.Models;
namespace FireLearn.ViewModels
{
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 ICommand RefreshCommand;
public CategoryViewModel()
{
loadFromSource();
RefreshCommand = new Command(async () =>
{
if (!ListRefreshing)
{
ListRefreshing = true;
try
{
await loadFromSource();
}
finally
{
ListRefreshing = false;
}
}
});
}
public async Task loadFromSource()
{
HttpClient httpClient = new()
{
Timeout = new TimeSpan(0,0,10)
};
Uri uri = new Uri("https://somewodpresssite/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");
}
}
}
The binding of the list works great and items show as expected (based on loadFromSource() being called in the constructor but the ICommand doesnt get called when I pull to refresh and I get the following error around the IsRefreshing binding:
[0:] Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics: Warning: 'ListRefreshing' property not found on 'FireLearn.ViewModels.CategoryViewModel', target property: 'Microsoft.Maui.Controls.ListView.IsRefreshing'
I have tried on Android and iOs with the same result and am at a loss as to what I've missed here.
CodePudding user response:
You can only bind to public properties
public bool ListRefreshing { get; set; }