Here is the XAML code for MainPage.xaml:
<?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"
x:Class="mauiApp.MainPage"
xmlns:viewmodel="clr-namespace:mauiApp.ViewModel"
x:DataType="viewmodel:MainViewModel">
<Grid RowDefinitions="100, Auto, *"
ColumnDefinitions=".75*,.25*"
Padding="10"
RowSpacing="10"
ColumnSpacing="10">
<Image Grid.ColumnSpan="2"
Source="dotnet_bot.png"
BackgroundColor="Transparent"/>
<Entry Placeholder="Enter task"
Text="{Binding Text}"
Grid.Row="1"/>
<Button Text="Add"
Command="{Binding AddCommand}"
Grid.Row="1"
Grid.Column="1"/>
<CollectionView Grid.Row="2"
Grid.ColumnSpan="2"
ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type x:String}">
<SwipeView>
<SwipeView.RightItems>
<SwipeItem Text="Delete"
BackgroundColor="Red"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}},Path=DeleteCommand}"
CommandParameter="{Binding .}"/>
</SwipeView.RightItems>
<Grid Padding="0,5">
<Frame>
<Label Text="{Binding .}"
FontSize="24"/>
</Frame>
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
Here is the C# code for MainViewModel.cs:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
namespace mauiApp.ViewModel
{
public partial class MainViewModel : ObservableObject
{
public MainViewModel()
{
Items = new ObservableCollection<string>();
}
[ObservableProperty]
ObservableCollection<string> items;
[ObservableProperty]
string text;
[RelayCommand]
void Add()
{
if(string.IsNullOrWhiteSpace(Text))
{
return;
}
Items.Add(Text);
Text = string.Empty;
}
[RelayCommand]
void Delete(string s)
{
if (Items.Contains(s))
{
Items.Remove(s);
}
}
}
}
Here is the C# code for MainProgram.cs:
using mauiApp.ViewModel;
namespace mauiApp;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
builder.Services.AddSingleton<MainPage>();
builder.Services.AddSingleton<MainViewModel>();
return builder.Build();
}
}
Here is the C# code for MainPage.xaml.cs:
using mauiApp.ViewModel;
namespace mauiApp
public partial class MainPage : ContentPage
{
public MainPage(MainViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
}
I am trying to learn MAUI, and I copied the following code from a tutorial on the 'dotnet' YouTube channel. However, the swipe-to-delete functionality in the CollectionView is not working as expected:
I suspect that RelativeSource
, inside a DataTemplate, is unable to traverse up the XAML tree that refers to that DataTemplate. OR it may be because the BindingContext of the DataTemplate is an individual item, not the page's BindingContext, so MainViewModel is not found.
An alternative technique is to use an x:Name
as a Source:
<ContentPage ...
x:Class="mauiApp.MainPage"
x:Name="thisPage"
...>
...
<SwipeItem ...
Command="{Binding BindingContext.DeleteCommand, Source={x:Reference thisPage}}"
CommandParameter="{Binding .}"/>
Or if you prefer this syntax:
Command="{Binding Source={x:Reference thisPage}, Path=BindingContext.DeleteCommand}"