C# Listview未基于ObservableCollection属性进行更新

C# Listview未基于ObservableCollection属性进行更新,c#,listview,xamarin,mvvm,binding,C#,Listview,Xamarin,Mvvm,Binding,我有一个BLE应用程序,它连接到设备,目的是在listview中动态接收设备状态。我将本机设备类实现为一个模型,我的viewmodel在MainViewModel类中是独立的。我在这两个类上都实现了INotifyPropretyChanged,但是连接到设备后,设备的状态没有改变。它应该是断开、连接、连接、断开的,我从这个BLE插件中获得了一个名为DeviceState的属性,该插件保存了这个值+我已经为它实现了一个INotifyPropretyChanged。我已经尝试了两种方法,一种是双向的

我有一个BLE应用程序,它连接到设备,目的是在listview中动态接收设备状态。我将本机设备类实现为一个模型,我的viewmodel在MainViewModel类中是独立的。我在这两个类上都实现了INotifyPropretyChanged,但是连接到设备后,设备的状态没有改变。它应该是断开、连接、连接、断开的,我从这个BLE插件中获得了一个名为DeviceState的属性,该插件保存了这个值+我已经为它实现了一个INotifyPropretyChanged。我已经尝试了两种方法,一种是双向的,另一种是NotifyCollectionChanged,等等。我成功地获得了设备名称和状态(断开连接),但是当我连接到它时,状态应该会改变,而不会改变。它成功地连接了,我在另一个没有MVVM方法的应用程序上尝试了它,它在连接后获得了状态,但我必须在循环中迭代这些状态,并将它们添加到单独的集合中,这并不是很有效。任何帮助都将不胜感激,提前谢谢

class NativeDevice : INotifyPropertyChanged
    {
        private string deviceNameValue = String.Empty;
        public event PropertyChangedEventHandler PropertyChanged;
        private DeviceState states;


        public NativeDevice(string name, DeviceState stated)
        {
            deviceNameValue = name;
            states = stated;
        }
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public string Name
        {
            get
            {
                return this.deviceNameValue;
            }

            set
            {
                if (value != this.deviceNameValue)
                {
                    this.deviceNameValue = value;
                    OnPropertyChanged();
                }
            }
        }
        
        public DeviceState States
        {
            get
            {
                return states;
            }

            set
            {
                this.states = value;
                OnPropertyChanged();
            }
        }
       


    }

当连接状态更改时,您需要更新UI绑定到的对象

有很多不同的方法来解决这个问题,一个简单的方法是

  async Task ConnectAsync()
    {
        foreach (var device in BluetoothDevices)
        {
            if (device.Name == "GP")
            {
                var parameters = new ConnectParameters(forceBleTransport: true);
                await _bluetoothAdapter.ConnectToDeviceAsync(device, parameters, source.Token);

                // find the matching device in DevicesFound
                var d = DevicesFound.Where(x => x.Name == device.Name).FirstOrDefault();
                d.States = DeviceState.Connected;
            }
        }
    }

我不清楚问题出在哪里。你是说当添加新设备时,它没有显示正确的状态吗?或者在添加后,当状态更改时,它不会更新?此外,您同时初始化了
设备查找
设备查找
,您应该只更新公共属性,而不是同时更新这两个属性。当我连接时,状态应该从断开更改为连接并连接,但它保持断开状态,因此不更新属性。首次添加设备时,初始状态是正确的。在初始连接后,您的代码中看不到任何将更新状态的内容。我没有连接到设备的方法。一旦它连接,状态应该改变,它的连接正确,但是状态没有改变,我想我已经将它正确绑定到属性上了,但是你没有发布代码
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:bleappmodelview="clr-namespace:BleAppModelView.ViewModels" xmlns:bleappmodelview1="clr-namespace:BleAppModelView.Model" x:DataType="bleappmodelview:MainViewModel"
             x:Class="BleAppModelView.MainPage">

    <ContentPage.BindingContext>
        <bleappmodelview:MainViewModel/>
    </ContentPage.BindingContext>

    <StackLayout>
       
        <Button x:DataType="bleappmodelview:MainViewModel"
                Text="Scan"
                Command="{Binding ScanForDevices}"
                Margin="10" />
        <ListView  ItemsSource="{Binding DevicesFound}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label x:DataType="bleappmodelview1:NativeDevice" Text="{Binding Name, Mode=TwoWay}"/>
                            <Label x:DataType="bleappmodelview1:NativeDevice" Text="{Binding States, Mode=TwoWay}" TextColor="Red"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button x:DataType="bleappmodelview:MainViewModel"
                Text="Connect" 
                Command="{Binding ConnectToDevices}"
                Margin="10"/>
    </StackLayout>


</ContentPage>
 public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            BindingContext = new MainViewModel();
        }
    }
namespace Plugin.BLE.Abstractions
{
    public enum DeviceState
    {
        Disconnected = 0,
        Connecting = 1,
        Connected = 2,
        Limited = 3
    }
}
 async Task ConnectAsync()
        {
            foreach (var device in BluetoothDevices)
            {
                if (device.Name == "GP")
                {
                    var parameters = new ConnectParameters(forceBleTransport: true);
                    await _bluetoothAdapter.ConnectToDeviceAsync(device, parameters, source.Token);
                }
            }
        }
  async Task ConnectAsync()
    {
        foreach (var device in BluetoothDevices)
        {
            if (device.Name == "GP")
            {
                var parameters = new ConnectParameters(forceBleTransport: true);
                await _bluetoothAdapter.ConnectToDeviceAsync(device, parameters, source.Token);

                // find the matching device in DevicesFound
                var d = DevicesFound.Where(x => x.Name == device.Name).FirstOrDefault();
                d.States = DeviceState.Connected;
            }
        }
    }