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