I'm developing a Maui app. I use a MVVM structure and the MVVM Community toolkit for an easier life. I now ran into a problem when displaying a ListView which is bound to a ObservableCollection in My Viewmodel.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WaiterEval.Views.UserList"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:vm="clr-namespace:WaiterEval.ViewModels"
x:DataType="vm:UserList_ViewModel">
<VerticalStackLayout>
<ListView x:Name="userList" ItemsSource="{Binding Users}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.25*" />
<ColumnDefinition Width="0.25*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding }" />
<Label
Grid.Row="0"
Grid.Column="1"
Text="{Binding Test}" />
<Label
Grid.Row="0"
Grid.Column="2"
Text="Edited" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</VerticalStackLayout>
</ContentPage>
namespace WaiterEval.ViewModels
{
public partial class UserList_ViewModel : ObservableObject
{
[ObservableProperty]
public ObservableCollection<User> users = new ObservableCollection<User>();
private readonly MyDbContext _dbContext;
public UserList_ViewModel(MyDbContext dbContext)
{
_dbContext = dbContext;
addUsers();
}
public async void addUsers()
{
try
{
Users = new ObservableCollection<User>(await _dbContext.Users.OfType<User>().ToListAsync());
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
The Collection is populated with Data after exiting the constructor.
namespace WaiterEval.Views;
public partial class UserList : ContentPage
{
public UserList(UserList_ViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
}
When trying to Bind something in the ListCell the Datacontext is the ViewModel and not the List like it is supposed to be. I can't access any properties of User. Where am I wrong here?
The x:DataType="vm:UserList_ViewModel"
in the <ContentPage>
will make the ContentPage and the children view bind to type of UserList_ViewModel.
You can declare the datatype for the ListView's item DataTemplate to make the item bind to type of User:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WaiterEval.Views.UserList"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:vm="clr-namespace:WaiterEval.ViewModels"
xmlns:models="clr-namespace:WaiterEval.Models"
x:DataType="vm:UserList_ViewModel">
<VerticalStackLayout>
<ListView x:Name="userList" ItemsSource="{Binding Users}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:User">
....
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</VerticalStackLayout>
</ContentPage>