Hallo,
ich habe in einer ContentPage ein wenig mit DataBinding in einem SwipeItem experimentiert und wollte dort ein Delete-Command einrichten, was aber nicht in der Person-Klasse selbst liegt und über das DataTemplate referenziert wird, sondern in es liegt in meiner ViewModel-Klasse "Tab2ViewViewModel".
Über folgenden Code komme ich irgendwie nicht an mein "DeleteItem" ran und weiß auch nicht, wie das ich dem Command-Handler meine aktuell zu löschende Person als Parameter mitgeben kann. Die Person-Klasse liegt unter dem Namespace "MyApp.Models" und die Command-Handler sind in der Klasse "Tab2ViewViewModel", welche im Namespace MyApp.ViewModels liegt.
<?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:viewmodel="clr-namespace:MyApp.ViewModels"
xmlns:models="clr-namespace:MyApp.Models"
x:DataType="viewmodel:Tab2ViewViewModel"
x:Class="MyApp.Pages.Tab2View"
Title="Tab 2 View">
<ContentPage.ToolbarItems>
<ToolbarItem IconImageSource="..." Command="{Binding AddNewItemCommand}" />
</ContentPage.ToolbarItems>
<Grid RowDefinitions="20, Auto" RowSpacing="10" Margin="20, 0, 20, 20">
<SearchBar Grid.Row="0" Grid.Column="0" Grid.RowSpan="5" Placeholder="Tab 2 Item search..." />
<CollectionView Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="0, 20, 0, 0"
ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type models:Person}">
<SwipeView>
<SwipeView.RightItems>
<SwipeItems>
<SwipeItem Text="Delete" BackgroundColor="Red"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:Tab2ViewViewModel}}, Path=DeleteItem}"
CommandParameter="{Binding .}"/>
</SwipeItems>
</SwipeView.RightItems>
<Grid Padding="0, 5">
<Frame>
<Label Text="{Binding Name}" FontAttributes="Bold" />
</Frame>
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MyApp.Models;
using System.Collections.ObjectModel;
namespace MyApp.ViewModels
{
public partial class Tab2ViewViewModel : ObservableObject
{
private static int _personCounter = 1;
[ObservableProperty]
private ObservableCollection<Person> items;
[ObservableProperty]
private Person personItem;
public Tab2ViewViewModel()
{
items = new ObservableCollection<Person>();
}
[RelayCommand]
private void AddNewItemCommand()
{
personItem = new Person();
personItem.Name = $"Person {_personCounter++}";
items.Add(personItem);
}
[RelayCommand]
private void DeleteItem(Person item)
{
if (items.Contains(item))
{
items.Remove(item);
}
}
}
}
Jetzt habe ich den Fehler gefunden - ist mir fast nicht aufgefallen:
Das MVVM-Toolkit erzeugt ja Code für die als
[RelayCommand]
attributierten Command-Handling-Methoden und baut da als Suffix noch ein "..Command" mit dazu.
Heißt also, mein Command-Handler heißt hier nicht "DeleteItem", sondern "DeleteItemCommand".
Mein Code bei den SwipeItems müsste also wie folgt aussehen:
...
<SwipeItems>
<SwipeItem Text="Delete" BackgroundColor="Red"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:Tab2ViewViewModel}}, Path=DeleteItemCommand}"
CommandParameter="{Binding .}"/>
</SwipeItems>
...
So kommt er dann über die RelativeSource und den AncestorType mit dem entsprechenden Path auch auf den Command-Handler drauf.
PS: Was mich nur sehr verwirrt hat, ich sehe bei Project > Dependencies > net7.0-android > Analyzers > CommunityToolkit.Mvvm.SourceGenerators > CommunityToolkit.Mvvm.SourceGenerators.RelayCommandGenerator bzw. den anderen Unterkategorien von CommunityToolkit.Mvvm.SourceGenerators nicht immer die Implementierungen, sondern ein schwarzes Symbol und nix weiter. Woran kann das denn liegen?