Reputation: 43
I have a .NET MAUI mobile app and I'm trying to implement a SearchHandler
with data binding from ViewModel
.
I have the code below, but I'm getting "No property, BindableProperty, or event found for "Clients", or mismatching type between value and property" error.
In ClientPage.xaml
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:Realizer.ViewModels"
xmlns:sh="clr-namespace:Realizer.Resources.SearchHandlers"
xmlns:models="clr-namespace:Realizer.Models"
x:DataType="vm:ClientsViewModel"
x:Class="Realizer.Pages.ClientsPage"
Title="Clients">
<Shell.SearchHandler>
<sh:ClientSearchHander ShowsResults="True"
Clients="{Binding Clients}"
DisplayMemberName="Name">
</sh:ClientSearchHander>
</Shell.SearchHandler>
In ClientSearchHandler.cs
namespace Realizer.Resources.SearchHandlers
{
public class ClientSearchHandler : SearchHandler
{
//public static readonly BindableProperty Clients;
public ObservableCollection<Client> Clients { get; set; }
protected override void OnQueryChanged(string oldValue, string newValue)
{
base.OnQueryChanged(oldValue, newValue);
if(string.IsNullOrWhiteSpace(newValue))
{
ItemsSource = null;
}
else
{
ItemsSource = Clients.Where(x => x.Name.Contains(newValue)).ToList();
}
}
protected override void OnItemSelected(object item)
{
base.OnItemSelected(item);
}
}
}
In ClientsViewModel.cs
public partial class ClientsViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<Client> _clients = new();
public async Task LoadClientsAsync()
{
var clients = await _context.GetAllAsync<Client>();
if (clients is not null && clients.Any())//if we have at least one client
{
Clients ??= new ObservableCollection<Client>(); //if null, initialize
foreach (var client in clients)
{
Clients.Add(client);
}
}
}
}
I saw someone asking the same question here and tried to make Clients
in ClientSearchHandler.cs
BindableProperty
as I have commented. But it conflicted when I set Client.Where(...)
saying "'BindableProperty' does not contain a definition for 'Where'."
Upvotes: 0
Views: 474
Reputation: 14444
As Jason said, you can create the BindableProperty for the Clients property. And I have tested it and make it work.
The ClientSearchHandler.cs:
public class ClientSearchHandler : SearchHandler
{
public static readonly BindableProperty ClientsProperty
= BindableProperty.Create("Clients", typeof(ObservableCollection<Client>), typeof(ClientSearchHandler), null);
public ObservableCollection<Client> Clients
{
get=>(ObservableCollection<Client>)GetValue(ClientsProperty);
set=>SetValue(ClientsProperty,value);
}
protected override void OnQueryChanged(string oldValue, string newValue)
{
base.OnQueryChanged(oldValue, newValue);
if (string.IsNullOrWhiteSpace(newValue))
{
ItemsSource = null;
}
else
{
ItemsSource = Clients.Where(x => x.Name.Contains(newValue)).ToList();
}
}
protected override void OnItemSelected(object item)
{
base.OnItemSelected(item);
}
}
And the result image:
If you have added the code about the bindableproperty, you can try to clean and rebuild the project to use it.
Upvotes: 1