Andreas Rainer
Andreas Rainer

Reputation: 344

Xamarin - Delete item from CollectionView, Command does not get called

I'm very new to Xamarin and i've built a simple app where you can add strings to an ObservableCollection and render it via a CollectionView Element. Now i've also made a delete Button next to each of these strings in the collection to delete one entry. Therefore i want to call my 'DeleteCommand'. But when i'm debugging the application i can see that the DeleteCommand in the Constructor doesn't get called when clicking on the delete Button. The command should get the string of the entry as parameter.

Here my XAML-Code:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:local="clr-namespace:TestProjectXamarin"
             mc:Ignorable="d"
             x:Class="TestProjectXamarin.MainPage">


    <ContentPage.BindingContext>
        <local:MainPageViewModel/>
    </ContentPage.BindingContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="2*"/>
            <RowDefinition Height=".5*"/>
            <RowDefinition Height="2*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Image Source="" BackgroundColor="PowderBlue"
               Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"/>
        <Editor Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Placeholder="Enter Note Here"
                Margin="10,10" Text="{Binding TheNote}"/>
        <Button Grid.Row="2" Grid.Column="0" Text="Save" Command="{Binding SaveCommand}" BackgroundColor="LimeGreen"/>
        <Button Grid.Row="2" Grid.Column="1" Text="Erase" Command="{Binding EraseCommand}" BackgroundColor="OrangeRed"/>

        <CollectionView x:Name="collectionView" ItemsSource="{Binding AllNotes}" Grid.Row="3" Grid.ColumnSpan="2">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout>
                        <Frame Margin="5">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height=".5*"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>

                                <Label Text="{Binding .}" Grid.Row="0"/>
                                <Button Text="Delete" Command="{Binding DeleteCommand}" CommandParameter="{Binding .}" Grid.Row="1"/>
                            </Grid>
                        </Frame>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>

</ContentPage>

And also my CS-Code:

    namespace TestProjectXamarin
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        public MainPageViewModel()
        {
            EraseCommand = new Command(() =>
            {
                TheNote = string.Empty;
            });

            SaveCommand = new Command(() =>
            {
                AllNotes.Add(TheNote);

                TheNote = string.Empty;
            });

            DeleteCommand = new Command<string>(
                execute: (string arg) =>
                {
                    TheNote = arg;
                }
            );
        }

        public ObservableCollection<string> AllNotes { get; set; } = new ObservableCollection<string>();

        public event PropertyChangedEventHandler PropertyChanged;

        string theNote;

        public string TheNote
        {
            get => theNote;
            set
            {
                theNote = value;
                var args = new PropertyChangedEventArgs(nameof(TheNote));

                PropertyChanged?.Invoke(this, args);
            }
        }

        public Command SaveCommand { get; }
        public Command EraseCommand { get; }
        public Command DeleteCommand { private set; get; }
    }
}

What am I doing wrong here? Can't i call a command out of such a CollectionView this way? Or is there a more propriet way for deleting an item?

Would be thankful if someone can help me on this!

Upvotes: 1

Views: 1136

Answers (1)

nevermore
nevermore

Reputation: 15816

The DeleteCommand is in your ViewModel so the solution is:

1.Define a name of your page, let's call it MyPage:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:App283"
             mc:Ignorable="d"

             x:Name="MyPage"

             x:Class="App283.MainPage">

2.Then bind your DeleteCommand like this:

<Button Text="Delete" Command="{Binding BindingContext.DeleteCommand, Source={x:Reference MyPage}}" CommandParameter="{Binding .}" Grid.Row="1"/>

Upvotes: 2

Related Questions