Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.net Maui Accessing the data item in a CollectionView when a button is clicked

Man this is like walking through treacle :(

Okay, so I have a class in a folder called models. I have a viewmodel in a folder called ViewModels and a Page that displays a list of Bluetooth connections - don't get excited it's only dummy data :sigh

enter image description here

So Here is the code BluetoothPeripheral.cs

namespace TSDZ2Monitor.Models;

public class BluetoothPeripheral
{
  public string Name    { get; set; }
  public string Id      { get; set; } 
  public bool   Enabled { get; set; }
}
namespace TSDZ2Monitor.ViewModels;

public partial class BluetoothPeripheralsViewModel : ObservableObject
{
  [ObservableProperty]
  public ObservableCollection<BluetoothPeripheral> bluetoothPeripherals = new()
  {
    new BluetoothPeripheral
    {
      Name = "Heart Rate Monitor",
      Id = "12:12:12:12:AB",
      Enabled = true
    },
    new BluetoothPeripheral
    {
      Name = "Speedometer",
      Id = "34:34:34:34:CD",
      Enabled = true
    },
    new BluetoothPeripheral
    {
      Name = "Cadence",
      Id = "56:56:56:56:EF",
      Enabled = true
    },
    new BluetoothPeripheral
    {
      Name = "TSDZ2Monitor Motor",
      Id = "78:78:78:78:GH",
      Enabled = true
    }
  };


  public ICommand DeleteBLEItemCommand => new Command(DeleteBLEItemControl);
  public void DeleteBLEItemControl(object o)
  {
    Console.WriteLine($"delete {o}");
  }
}

and the BluetoothPage.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"
             xmlns:local="clr-namespace:TSDZ2Monitor.ViewModels"
             x:Class="TSDZ2Monitor.Pages.BluetoothPage"
             Title="Bluetooth Page">

  <ContentPage.BindingContext>
    <local:BluetoothPeripheralsViewModel />
  </ContentPage.BindingContext>


  <StackLayout>
    <Label Text="Bluetooth LE Connections" />
    <Label Text="{Binding Test}" />

    <CollectionView
      ItemsSource="{Binding BluetoothPeripherals}"
      EmptyView="No data available"
      VerticalOptions="StartAndExpand"
      SelectionMode="Single"
      ItemsLayout="VerticalList"
      HeightRequest="240">
      <CollectionView.ItemTemplate>
        <DataTemplate>
          <Grid
             ColumnDefinitions="*,*,auto">

            <Label Grid.Column="0" 
                   Text="{Binding Name}"
                   FontSize="20"
                   TextColor="Yellow"/>
            <Label Grid.Column="1" 
                   Text="{Binding Id}" 
                   FontSize="20"
                   TextColor="Yellow"/>
            <Button Grid.Column="2" 
                    Text="Del" 
                    WidthRequest="50"
                    HeightRequest="20"
                    Command="{Binding Source={RelativeSource AncestorType={x:Type local:BluetoothPeripheralsViewModel}}, Path=DeleteBLEItemCommand}"
                    CommandParameter="{Binding}"/>

          </Grid>
        </DataTemplate>
      </CollectionView.ItemTemplate>
    </CollectionView>


  </StackLayout>
</ContentPage>

Now the list displays - yay to me after hours of searching.

I click the button on a list item and it calls the DeleteBLEItemCommand which calls the DeleteBLEItemControl - using the ancestor thing! After even more hours.

Now I want to get access to the object (probably so I can delete it from my list or do other things)

Now if I put a breakpoint on the Console.WriteLine and open up an immediate window I can type in o and I get

o
{TSDZ2Monitor.Models.BluetoothPeripheral}
    Enabled: true
    Id: "56:56:56:56:EF"
    Name: "Cadence"

but if I type o.Name in the immediate window

o.Name
Unknown member: Name

Uh???

I admit C# at this level isn't my thing (yet) but it's there so why can't I access it? Please help me, or show me a better way.

btw is there some documentation or tutorial somewhere that really explains what is going on and has some simple working examples (rather than the contrived and overly complex MS examples in the docs)?

Thanks again. G

like image 678
gfmoore Avatar asked Oct 23 '25 22:10

gfmoore


1 Answers

you are specifying type object. Either cast it to the correct type, or use Command<T> to specify the type

public ICommand DeleteBLEItemCommand => new Command<BluetoothPeripheral>(DeleteBLEItemControl);

public void DeleteBLEItemControl(BluetoothPeripheral o)
{
  Console.WriteLine($"delete {o}");
}
like image 177
Jason Avatar answered Oct 26 '25 13:10

Jason



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!