Search code examples
c#xamarinxamarin.formsxamarin.forms.listview

Button to delete current ListView Row in Xamarin.Forms


I am using data binding to populate a ListView from an SQLite DB. I would like the user to be able to press a Button and for the current row to be deleted.

Page1.xaml:

  <ListView x:Name="recentUserList" Margin="20,0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
            <ListView.ItemTemplate>
                <DataTemplate >
                    <ViewCell>
                        <Frame Padding="5" Margin="0,0,0,5">
                            <Grid HeightRequest="50" HorizontalOptions="FillAndExpand" VerticalOptions="Start">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Label Grid.Column="0" Text="{Binding UserName}"/>
                                <Button Grid.Column="3" Text="Delete" Clicked="BtnDelete_Clicked" />
                            </Grid>
                        </Frame>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

Page1.cs:

protected override void OnAppearing()
{
        base.OnAppearing();
        recentUserList.ItemsSource = App.Database.GetUserList();
}

private void BtnDelete_Clicked(object sender, EventArgs e)
{
        var user = sender as User;
        recentUserList.Remove(user);
}

Database:

public List<User> GetUserList()
{
    return database.Query<User>("SELECT * FROM User;");
}

User.cs:

 public class User: INotifyPropertyChanged
 {
        [PrimaryKey, AutoIncrement]
        public int ID { get; set; }
        private string userName;
        public string UserName
        {
            get
            {
                return userName;
            }
            set
            {
                if (userName!= value)
                {
                    userName = value;
                    OnPropertyChanged("UserName");
                }
            }
        }
}

This results in the following error for Remove in recentUserList.Remove(user); in Page1.cs.

Error CS7036: There is no argument given that corresponds to the required formal parameter 'value' of 'CollectionExtensions.Remove<TKey, TValue>(IDictionary<TKey, TValue>, TKey, out TValue)'

How can I make it so it is possible to click the button to delete the given ListView item/row?


Solution

  • The sender object is of type Button not User, although it BindingContext property is of type User in this case:

    private void BtnDelete_Clicked(object sender, EventArgs e)
    {
            var btn = sender as Button;
            var user = btn.BindingContext as User;
            //recentUserList.Remove(user);
    }
    
    

    Also recentUserList is a ui element (ListView) it does not have a .Remove() method. What you need to do is to bind it ItemsSource to an ObservableCollection whic you will call the .Remove() method.

    I highly invite you to read the related documentation