Search code examples
mvvmmauimaui-community-toolkit

Binding: Property not found on ViewModel when using CollectionView in MAUI 8.0


I am following this link to add a CollectionView to my XAML page but I get

Binding: Property "AccountNumber" not found on "***GlAccountsViewModel" .

Visual Studio's intelligence shows and navigates correctly when I click on AccountNumber but when I try to run the app, I get this error.

Here is my code:

public class GlAccount
{
    public string AccountNumber { get; set; }
}
    
public sealed partial class GlAccountsViewModel : ObservableObject
{
    private readonly GlAccountService _glAccountService;

    [ObservableProperty] private bool isRefreshing;

    [ObservableProperty]
    private IEnumerable<GlAccount> _accounts = new List<GlAccount>();
    
    public GlAccountsViewModel(GlAccountService glAccountService)
    {
        _glAccountService = glAccountService;
    }

    [RelayCommand]
    async Task OnAppearing()
    {
        await Refresh();
    }

    [RelayCommand]
    async Task Refresh()
    {
        Accounts = await _glAccountService.GetAllAsync();
        IsRefreshing = false;
    }
}

  xmlns:vm="clr-namespace:MyProjectName.ViewModels.GlAccount"
  x:Class="MyProjectName.Pages.GlAccount.GlAccountsPage"
  x:TypeArguments="vm:GlAccountsViewModel"
  x:DataType="vm:GlAccountsViewModel"
  
<RefreshView IsRefreshing="{Binding IsRefreshing}"
         Command="{Binding RefreshCommand}">
 <CollectionView ItemsSource="{Binding Accounts}">
     <CollectionView.ItemTemplate>
         <DataTemplate>
             <Grid Padding="10">
                 <Grid.RowDefinitions>
                     <RowDefinition Height="Auto" />
                 </Grid.RowDefinitions>
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition Width="Auto" />
                 </Grid.ColumnDefinitions>
                 <Label Text="{Binding AccountNumber}"/>
             </Grid>
         </DataTemplate>
     </CollectionView.ItemTemplate>
 </CollectionView>
</RefreshView>

I tried with but no luck.

private ObservableCollection<GlAccount> _accounts = new ObservableCollection<GlAccount>();

What am I missing here?


Solution

  • That may relate to Compiled bindings.

    To use compiled bindings, set an x:DataType attribute on a VisualElement to the type of the object that the VisualElement and its children will bind to. It's recommended to set the x:DataType attribute at the same level in the view hierarchy as the BindingContext is set. However, this attribute can be re-defined at any location in a view hierarchy.

    Since you have set the x:DataType="vm:GlAccountsViewModel" for the ContentPage, the type of object each item in CollectionView binds to has also been changed.

    So, we can redifine x:DataType in the DataTemplate of the CollectionView

    <CollectionView ItemsSource="{Binding Accounts}">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="model:GlAccount">
                <Grid Padding="10">
                    <Grid.RowDefinitions>
    

    Then the type of its data object is defined to GlAccount. Thus the AccountNumber property could be found.

    Hope it helps!