.net Maui 单击按钮时访问 CollectionView 中的数据项

gfm*_*ore 4 .net data-binding maui

伙计,这就像走过糖蜜:(

好的,我在名为 models 的文件夹中有一个类。我在名为 ViewModels 的文件夹中有一个视图模型,还有一个显示蓝牙连接列表的页面 - 不要兴奋,这只是虚拟数据:叹息

在此输入图像描述

所以这是代码BluetoothPeripheral.cs

namespace TSDZ2Monitor.Models;

public class BluetoothPeripheral
{
  public string Name    { get; set; }
  public string Id      { get; set; } 
  public bool   Enabled { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
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}");
  }
}
Run Code Online (Sandbox Code Playgroud)

和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>
Run Code Online (Sandbox Code Playgroud)

现在列表显示 - 经过几个小时的搜索后,对我来说是的。

我单击列表项上的按钮,它会调用DeleteBLEItemCommand,后者调用DeleteBLEItemControl - 使用祖先的东西!又过了几个小时。

现在我想访问该对象(可能这样我可以将其从列表中删除或执行其他操作)

现在,如果我在 Console.WriteLine 上放置一个断点并打开一个即时窗口,我可以输入 o 并得到

o
{TSDZ2Monitor.Models.BluetoothPeripheral}
    Enabled: true
    Id: "56:56:56:56:EF"
    Name: "Cadence"
Run Code Online (Sandbox Code Playgroud)

但如果我在立即窗口中输入 o.Name

o.Name
Unknown member: Name
Run Code Online (Sandbox Code Playgroud)

呃???

我承认这个级别的 C# 还不是我的菜,但它就在那里,为什么我不能访问它呢?请帮助我,或者告诉我更好的方法。

顺便说一句,是否有一些文档或教程真正解释了正在发生的事情并有一些简单的工作示例(而不是文档中人为且过于复杂的 MS 示例)?

再次感谢。G

Jas*_*son 5

您正在指定类型对象。要么将其转换为正确的类型,要么使用Command<T>指定类型

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

public void DeleteBLEItemControl(BluetoothPeripheral o)
{
  Console.WriteLine($"delete {o}");
}
Run Code Online (Sandbox Code Playgroud)