Home > Back-end >  Xamarin.Forms - How to select item from its containing ListView with ObservableCollection
Xamarin.Forms - How to select item from its containing ListView with ObservableCollection

Time:07-11

I have an ListView bound to an ObservableCollection<ItemID> as shown. When I click a Delete button it calls DeleteButton_Clicked correctly but then cannot access the objects. I need to delete object and then change the Scan.Text property. Thank you for any help.

List with items

The ItemID class is defined here:

public class ItemID
{
    public string Name { get; set; }
    public string Age { get; set; }
    public double Value { get; set; }
}

This is code that's giving me trouble:

private void DeleteButton_Clicked(object sender, EventArgs e)
{
    ItemID items = MyList.SelectedItem as ItemID;
        
    Items.Remove(items);
    MyList.SelectedItem = null;
    Scan.Text = items.Value.ToString(); // it doesn't work
}

The Scan button creates an object and also changes the Scan.Text:

private async void ButtonScanDefault_Clicked(object sender, EventArgs e)
{
    ZXingScannerPage scanPage;
    scanPage = new ZXingScannerPage();

    scanPage.OnScanResult  = (result) =>
    {
        scanPage.IsScanning = false;

        Device.BeginInvokeOnMainThread(async () =>
        {
            await Navigation.PopModalAsync();
            await DisplayAlert("Scanned Barcode", result.Text, "OK");


            Scan.Text = SumCost(Cost_Product(result.Text));

            var item = new ItemID()
            {
                Name = "Name_ID:"   " "   result.Text,
                Age = "Age:"   " "   Cost_Product(result.Text),
                Value = Cost_Product(result.Text)
            };
            Items.Add(item);

        });
    };
    await Navigation.PushModalAsync(scanPage);
}

XAML

<ListView Grid.Row="1"
            ItemsSource="{Binding Items}"
            HasUnevenRows="True"
            x:Name="MyList">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Label Text="{Binding Name}" />

                    <Button Clicked="DeleteButton_Clicked"
                            Grid.Column="1"
                            Padding="30,10"
                            Text="Delete"
                            HorizontalOptions="EndAndExpand"
                            BackgroundColor="Black"
                            TextColor="White" />
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

CodePudding user response:

Here's what could be the problem: In your DeleteButton_Clicked you rely on the SelectedItem property of MyList. However, clicking the Delete button does not automatically select that list item. The way to determine the correct item to delete is to look at the BindingContext property of the button that sent the delete click, and cast this object to ItemID.

private void DeleteButton_Clicked(object sender, EventArgs e)
{
    // The sender is the button you clicked
    Button button = (Button)sender;

    // The binding context of the button IS the
    // item associated with the button.
    ItemID item = (ItemID)button.BindingContext;
    Items.Remove(item);

    // Now you can adjust the Scan.Text however you want.
    // THIS IS JUST AN EXAMPLE
    ItemID defaultScanItem = Items.FirstOrDefault();
    if (defaultScanItem == null)
    {
        Scan.Text = $"[Deleted {item.Name}]";
    }
    else
    {
        Scan.Text = $"[Deleted {item.Name}] Scan {defaultScanItem.Name}";
    }
}

Before and after delete

Before and after delete

  • Related