in my simple .NET MAUI MVVM project. Button Click event not hitting. Code is below
XAML
<......
xmlns:vm="clr-namespace:MVVMSqliteCrudNet8.ViewModels"
xmlns:models="clr-namespace:MVVMSqliteCrudNet8.Models"
x:DataType="vm:ProductsViewModel"
x:Class="MVVMSqliteCrudNet8.MainPage"
Title="MVVM SQlite Crud Net8">
HorizontalOptions="Center"
IsVisible="{Binding IsBusy}">
HorizontalOptions="Center"/>
VerticalOptions="Center"
HorizontalOptions="Center"/>
Text="Products"
FontAttributes="Bold"
FontSize="18"
Padding="10"/>
RowSpacing="5"
Padding="5"
BackgroundColor="#ECECEC">
Grid.Column="0"
Text="{Binding Name}"
FontAttributes="Bold" />
Grid.Column="0"
Text="{Binding Price, StringFormat='Price: {0}'}"
FontSize="12"
FontAttributes="Bold" />
Grid.Column="1"
Text="Edit"
Padding="0"
HeightRequest="25"
FontSize="12"
CornerRadius="2"
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:ProductsViewModel}}, Path=SetOperatingProductCommand}"
CommandParameter="{Binding .}"/>
Grid.Column="1"
Text="Del"
Padding="0"
HeightRequest="25"
FontSize="12"
CornerRadius="2"
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:ProductsViewModel}}, Path=DeleteProductCommand}"
CommandParameter="{Binding Id}" />
FontSize="18"
FontAttributes="Bold"
HorizontalTextAlignment="Center"/>
Padding="10"
RowSpacing="10"
ColumnSpacing="10"
BackgroundColor="#CCBFFA">
Margin="0"
BackgroundColor="#DAD1F9"/>
Margin="0"
BackgroundColor="#DAD1F9"
Keyboard="Numeric"/>
Grid.ColumnSpan="2"
Text="Update Product"
HorizontalOptions="Center"
VerticalOptions="End"
CornerRadius="4"
Padding="50, 0"
Command="{Binding SaveProductCommand}"
>
Value="0">
MVVM
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MVVMSqliteCrudNet8.Data;
using MVVMSqliteCrudNet8.Models;
namespace MVVMSqliteCrudNet8.ViewModels;
public partial class ProductsViewModel : ObservableObject
{
private readonly DatabaseContext _context;
public ProductsViewModel(DatabaseContext context)
{
_context = context;
}
[ObservableProperty]
private ObservableCollection
[ObservableProperty]
private Product _operatingProduct = new();
[ObservableProperty]
private bool _isBusy;
[ObservableProperty]
private string _busyText;
public async Task LoadProductsAsync()
{
await ExecuteAsync(async () =>
{
var products = await _context.GetAll
if (products is not null && products.Any())
{
Products ??= new ObservableCollection
foreach (var product in products)
{
Products.Add(product);
}
}
}, "Fetching products...");
}
[RelayCommand]
private void SetOperatingProduct(Product? product) => OperatingProduct = product ?? new();
[RelayCommand]
private async Task SaveProductAsync()
{
if (OperatingProduct is null)
return;
var busyText = OperatingProduct.Id == 0 ? "Creating product..." : "Updating product...";
await ExecuteAsync(async () =>
{
if (OperatingProduct.Id == 0)
{
// Create product
await _context.AddItemAsync
Products.Add(OperatingProduct);
}
else
{
// Update product
if (await _context.UpdateItemAsync
{
var productCopy = OperatingProduct.Clone();
var index = Products.IndexOf(OperatingProduct);
Products.RemoveAt(index);
Products.Insert(index, productCopy);
}
else
{
await Shell.Current.DisplayAlert("Error", "Product updation error", "Ok");
return;
}
}
SetOperatingProductCommand.Execute(new());
}, busyText);
}
[RelayCommand]
private async Task DeleteProductAsync(int id)
{
await ExecuteAsync(async () =>
{
if (await _context.DeleteItemAsync
{
var product = Products.FirstOrDefault(p => p.Id == id);
Products.Remove(product);
}
else
{
await Shell.Current.DisplayAlert("Delete Error", "Product was not deleted", "Ok");
}
}, "Deleting product...");
}
private async Task ExecuteAsync(Func
{
IsBusy = true;
BusyText = busyText ?? "Processing...";
try
{
await operation?.Invoke();
}
catch (Exception ex)
{
string s = ex.Message;
}
finally
{
IsBusy = false;
BusyText = "Processing...";
}
}
}
Code Behind
using MVVMSqliteCrudNet8.ViewModels;
namespace MVVMSqliteCrudNet8
{
public partial class MainPage : ContentPage
{
ProductsViewModel viewModels;
public MainPage(ProductsViewModel _viewModels)
{
InitializeComponent();
BindingContext = viewModels;
viewModels = _viewModels;
}
protected override async void OnAppearing()
{
base.OnAppearing();
await viewModels.LoadProductsAsync();
}
}
}

Mushtaq M APosted Nov 11, 2023, 4:15 AM
Change the following from
to
since the error may be occurred due to the null view model to binding context. hence the MVVM wiring may not happened.