来自接口的 Observablecollection 通过绑定添加到列表视图

Observablecollection from interface add to listview via binding

我有一个使用 Xabre.ble 插件的应用程序。

当应用程序扫描设备时,一旦发现设备,应用程序就会将其附加到派生自接口的 ObservableCollection。

我在 Xaml 中制作了一个数据模板,我希望填充它,但由于某些原因,我似乎无法正确设置 BindingContext。

基本上,我想要实现的是将设备对象添加到我的 ObservableCollection IDevice,并仅获取绑定上下文中各个设备的名称,供用户在列表视图

Xaml:

<ListView x:Name="deviceList">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/> 
                        <ColumnDefinition Width="Auto"/>
                   </Grid.ColumnDefinitions>
                   <local:IconView Grid.Row="0" Grid.Column="0" Source="BLE.png" Foreground="#3b5998" WidthRequest="30" HeightRequest="30"/>
                   <Label Grid.Row="1" Text="{Binding DeviceName}" TextColor="Teal"/>
                </Grid>
            </ViewCell>
        </DataTemplate> 
    </ListView.ItemTemplate>
</ListView>

CS:

public ObservableCollection<IDevice> Devices { get; set; }
IAdapter adapter = CrossBluetoothLE.Current.Adapter;
public ObservableCollection<string> DeviceName { get; set; }

public MainPage()
{
    //Instantiate observable collection
    Devices = new ObservableCollection<IDevice>();
    DeviceName = new ObservableCollection<string>();

    //Appending peripherals to list
    BindingContext = DeviceName;
    deviceList.ItemsSource = BindingContext;
    Content = deviceList;
    Refreshcmd();
}
public void Refreshcmd()
{
//DeviceDiscovered is an event, when it discovers a device, we fire the eventhandler
    adapter.DeviceDiscovered += (s, a) =>
    {
        if (a.Device.Name != null)
        {
            Devices.Add(a.Device);               
            DeviceName.Add(a.Device.Name);
        }
    };
    adapter.StartScanningForDevicesAsync();
}

如您所见,我尝试创建一个对象,其中包含仅包含 IDevice 名称的字符串。但是,它不会附加到我的数据绑定 DeviceName

此外,我不太喜欢这个解决方案,因为我更希望能够从界面访问 Devices.Name,但这显然是不允许的。 - 我更喜欢该解决方案的原因是用户最终将不得不连接到列表中的设备,这意味着为所有 "behind the scenes" 细节拥有一个对象要容易得多。

您应该将代码重构为 MVVM 方法。

namespace YourNameSpace.ViewModels
{
    public class YourViewModel
    {

        private ObservableCollection<IDevice> devices;
        public ObservableCollection<IDevice> Devices
        {
            get { return devices; }
            set
            {
                devices = value;
            }
        }
        public YourViewModel()
        {
            Devices = new ObservableCollection<IDevice>();
        }
    }
}

在你的Page.xaml.cs

public partial class YourPage : ContentPage
    {
        public YourPage()
        {
            InitializeComponent();
            BindingContext = new YourViewModel();
        }
    }

    public void Refreshcmd()
{
//DeviceDiscovered is an event, when it discovers a device, we fire the eventhandler
    adapter.DeviceDiscovered += (s, a) =>
    {
        if (a.Device.Name != null)
        {
            (YourViewModel)Devices.Add(a.Device);               
            //DeviceName.Add(a.Device.Name);
        }
    };
    adapter.StartScanningForDevicesAsync();
}

然后在Page.xaml

 <ListView ItemsSource="{Binding Devices}"
              CachingStrategy="RecycleElement">