Hi,
I'm encountering an issue with data binding in my .NET MAUI app while using the CommunityToolkit.MVVM package.
I'm implementing the MVVM pattern and trying to bind API responses to the HomePage ViewModel. However, the binding isn't updating as expected, even though the properties are set up correctly with ObservableProperty and are being updated in the ViewModel.
<Label Text="{Binding User.Name , FallbackValue='Loading...'}" FontSize="24" FontAttributes="Bold" TextColor="White" HorizontalOptions="Center" /> </VerticalStackLayout>
So, requesting you to please help me here
Please let me know if any additional information is needed to troubleshoot this issue. Thank you!
Here’s a snippet of the relevant code:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LeaveMatrix.Models;
using LeaveMatrix.Services.Interfaces;
namespace LeaveMatrix.ViewModels
{
public partial class HomePageViewModel : ObservableObject
{
[ObservableProperty]
private User _user;
[ObservableProperty]
private List<Colleague> _colleagues;
[ObservableProperty]
private LeaveSummary _leaveSummary;
private readonly IHomeService _homeService;
public HomePageViewModel(IHomeService homeService)
{
_homeService = homeService;
}
public async Task InitializeAsync()
{
await PopulateHomePage();
}
[RelayCommand]
public async Task PopulateHomePage()
{
try
{
//string token = await SecureStorage.GetAsync("AuthToken");
//if (!string.IsNullOrEmpty(token))
//{
// HomePageResponse homePageResponse = await _homeService.GetHomaPage(token);
// if (homePageResponse != null)
// {
// user = homePageResponse.User;
// colleagues = homePageResponse.Colleagues;
// leaveSummary = homePageResponse.LeaveSummary;
// }
//}
_user = new User
{
Name = "Test Arnab"
};
}
catch (Exception ex)
{
await Shell.Current.DisplayAlert("Error", ex.Message, "OK");
}
}
}
}
using LeaveMatrix.ViewModels;
namespace LeaveMatrix.Views;
public partial class HomePage : ContentPage
{
private readonly HomePageViewModel _homeVM;
public HomePage(HomePageViewModel homeVM)
{
InitializeComponent();
_homeVM = homeVM;
BindingContext = _homeVM;
}
protected override async void OnAppearing()
{
base.OnAppearing();
await _homeVM.InitializeAsync();
}
}
<?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:icon="clr-namespace:LeaveMatrix.Helpers"
xmlns:vm="clr-namespace:LeaveMatrix.ViewModels"
x:Class="LeaveMatrix.Views.HomePage"
x:DataType="vm:HomePageViewModel"
Title="Home"
BackgroundColor="#FFFFFF"
>
<ScrollView>
<Grid RowDefinitions="Auto,Auto">
<Grid Grid.Row="0">
<Image Source="navbar.png"
Aspect="Fill"
HorizontalOptions="Fill"
VerticalOptions="Fill" />
<Frame BackgroundColor="Transparent"
BorderColor="Transparent"
Margin="10,20"
HorizontalOptions="Center"
VerticalOptions="Start">
<VerticalStackLayout HorizontalOptions="Fill" VerticalOptions="CenterAndExpand">
<Border StrokeShape="Ellipse" WidthRequest="150" HeightRequest="150" Stroke="Transparent">
<Image Source="{Binding User.ProfileImageURL, FallbackValue='Loading...', Converter={StaticResource ImageUrlConverter}}" HorizontalOptions="Center" />
</Border>
<BoxView HeightRequest="20" Background="Transparent" />
<Label Text="Welcome back," FontSize="18" TextColor="White" HorizontalOptions="Center"/>
<Label Text="{Binding User.Name , FallbackValue='Loading...'}" FontSize="24" FontAttributes="Bold" TextColor="White" HorizontalOptions="Center" />
</VerticalStackLayout>
</Frame>
</Grid>
<Grid Grid.Row="1">
<VerticalStackLayout Padding="20" Spacing="15" Margin="0,0,0,5">
<!-- Dashboard Section -->
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="Center">
<!-- Define two columns -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Label in the first column -->
<Label
Text="Dashboard"
FontSize="18"
FontAttributes="Bold"
TextColor="#333333"
HorizontalOptions="Start"
VerticalOptions="Center"
Grid.Column="0" />
<Frame
Grid.Column="1"
HorizontalOptions="End"
VerticalOptions="Center"
BackgroundColor="Transparent"
BorderColor="#00AFB9"
CornerRadius="20"
Padding="0"
HasShadow="False">
<HorizontalStackLayout Padding="10,0" Spacing="5" VerticalOptions="Center">
<Label
Text="Leave History"
FontSize="14"
TextColor="#00A9C9" />
<Label
Text="{x:Static icon:IconFontFaSolid.ArrowRight}"
FontFamily="FaSolid"
FontSize="16"
TextColor="#00AFB9"
VerticalOptions="Center" />
</HorizontalStackLayout>
</Frame>
</Grid>
<Grid ColumnDefinitions="*,*,*" RowDefinitions="Auto,Auto" ColumnSpacing="12" RowSpacing="12">
<!-- Casual Leave -->
<Frame BackgroundColor="White"
CornerRadius="10" Padding="10"
Grid.Row="0" Grid.Column="0" Margin="0"
HasShadow="True">
<StackLayout>
<Image Source="calendar.png" WidthRequest="30" HeightRequest="30" HorizontalOptions="Start" />
<Label HorizontalTextAlignment="End">
<Label.FormattedText>
<FormattedString>
<Span Text="07" FontSize="Title"/>
<Span Text="/17" FontSize="Small"/>
</FormattedString>
</Label.FormattedText>
</Label>
<Label Text="Casual" FontSize="15"
TextColor="Black"
HorizontalTextAlignment="Start"
FontAttributes="Bold" Margin="0,10,0,0" />
</StackLayout>
</Frame>
<!-- Medical Leave -->
<Frame BackgroundColor="White"
CornerRadius="10" Padding="10"
Grid.Row="0" Grid.Column="1" Margin="0"
HasShadow="True">
<StackLayout>
<Image Source="healthcare.png" WidthRequest="30" HeightRequest="30" HorizontalOptions="Start" />
<Label HorizontalTextAlignment="End">
<Label.FormattedText>
<FormattedString>
<Span Text="10" FontSize="Title"/>
<Span Text="/14" FontSize="Small"/>
</FormattedString>
</Label.FormattedText>
</Label>
<Label Text="Medical" FontSize="15"
TextColor="Black"
HorizontalTextAlignment="Start"
FontAttributes="Bold" Margin="0,10,0,0" />
</StackLayout>
</Frame>
<!-- Restricted Holiday -->
<Frame BackgroundColor="White"
CornerRadius="10"
Padding="10"
Grid.Row="0"
Grid.Column="2"
Margin="0"
HasShadow="True">
<StackLayout>
<Image Source="leave.png" WidthRequest="30" HeightRequest="30" HorizontalOptions="Start" />
<Label HorizontalTextAlignment="End">
<Label.FormattedText>
<FormattedString>
<Span Text="0" FontSize="Title"/>
<Span Text="/04" FontSize="Small"/>
</FormattedString>
</Label.FormattedText>
</Label>
<Label Text="Restricted" FontSize="15"
TextColor="Black"
HorizontalTextAlignment="Start"
FontAttributes="Bold" Margin="0,10,0,0" />
</StackLayout>
</Frame>
<!-- Marriage Leave -->
<Frame BackgroundColor="White"
CornerRadius="10" Padding="10"
Grid.Row="1" Grid.Column="0" Margin="0"
HasShadow="True">
<StackLayout>
<Image Source="bride.png" WidthRequest="30" HeightRequest="30" HorizontalOptions="Start" />
<Label HorizontalTextAlignment="End">
<Label.FormattedText>
<FormattedString>
<Span Text="05" FontSize="Title"/>
<Span Text="/05" FontSize="Small"/>
</FormattedString>
</Label.FormattedText>
</Label>
<Label Text="Marriage" FontSize="15"
TextColor="Black"
HorizontalTextAlignment="Start"
FontAttributes="Bold" Margin="0,10,0,0" />
</StackLayout>
</Frame>
<!-- Maternity Leave -->
<Frame BackgroundColor="White" Padding="10"
CornerRadius="10"
Grid.Row="1"
Grid.Column="1"
HasShadow="True"
Margin="0">
<StackLayout>
<Image Source="maternity_care.png" WidthRequest="30" HeightRequest="30" HorizontalOptions="Start" />
<Label HorizontalTextAlignment="End">
<Label.FormattedText>
<FormattedString>
<Span Text="60" FontSize="Title"/>
<Span Text="/50" FontSize="Small"/>
</FormattedString>
</Label.FormattedText>
</Label>
<Label Text="Maternity"
FontSize="15"
TextColor="Black"
HorizontalTextAlignment="Start"
FontAttributes="Bold"
Margin="0,10,0,0" />
</StackLayout>
</Frame>
<!-- Bereavement Leave -->
<Frame BackgroundColor="White"
CornerRadius="10"
Padding="10"
Grid.Row="1"
Grid.Column="2"
Margin="0"
HasShadow="True">
<StackLayout>
<Image Source="candles.png" WidthRequest="30" HeightRequest="30" HorizontalOptions="Start" />
<Label HorizontalTextAlignment="End">
<Label.FormattedText>
<FormattedString>
<Span Text="0" FontSize="Title"/>
<Span Text="/02" FontSize="Small"/>
</FormattedString>
</Label.FormattedText>
</Label>
<Label Text="Bereavement" FontSize="15"
TextColor="Black"
HorizontalTextAlignment="Start"
FontAttributes="Bold" Margin="0,10,0,0" />
</StackLayout>
</Frame>
</Grid>
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="Center" Margin="0,0,0,10">
<!-- Define two columns -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Label in the first column -->
<Label
Text="Colleague's on leave"
FontSize="18"
FontAttributes="Bold"
TextColor="#333333"
HorizontalOptions="Start"
VerticalOptions="Center"
Grid.Column="0" />
<Frame
Grid.Column="1"
HorizontalOptions="End"
VerticalOptions="Center"
BackgroundColor="Transparent"
BorderColor="#00AFB9"
CornerRadius="20"
Padding="0"
HasShadow="False">
<HorizontalStackLayout Padding="10,0" Spacing="5" VerticalOptions="Center">
<Label
Text="Full List"
FontSize="14"
TextColor="#00A9C9" />
<Label
Text="{x:Static icon:IconFontFaSolid.ArrowRight}"
FontFamily="FaSolid"
FontSize="16"
TextColor="#00AFB9"
VerticalOptions="Center" />
</HorizontalStackLayout>
</Frame>
</Grid>
<CollectionView ItemsLayout="HorizontalList" HeightRequest="120">
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame BorderColor="#00AFB9" CornerRadius="10" Padding="10" WidthRequest="100" Margin="5">
<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Image Source="user_placeholder.png" WidthRequest="50" HeightRequest="50" HorizontalOptions="Center" />
<Label Text="{Binding Name}" FontSize="14" TextColor="#333333" HorizontalOptions="Center" />
<Label Text="{Binding LeaveDate}" FontSize="12" TextColor="#666666" HorizontalOptions="Center" />
</VerticalStackLayout>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</Grid>
</Grid>
</ScrollView>
</ContentPage>