c# - Xamarin Forms ListView 绑定未更新
问题描述
我有个问题。我用 ViewModel 创建了一个 ListView。在我的 ListView 中,我有一些带有文本的标签,这些标签绑定到 ItemSource 中的对象。现在,当我更改 ObservableCollection 中项目的 ViewModel 中的值时,屏幕上没有任何变化!
这是我的视图模型:
public class VM_DeviceList : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ICommand cmdDeleteDevice
{
get
{
return new Command<int>((x) => DeleteDevice_Handler(x));
}
}
public ICommand cmdTogglePower
{
get
{
return new Command<int>((x) => TogglePower_Handler(x));
}
}
private ObservableCollection<DisplayedDevice> _knownDeviceList;
public ObservableCollection<DisplayedDevice> knownDeviceList
{
get
{
return _knownDeviceList;
}
set
{
if (_knownDeviceList != value)
{
_knownDeviceList = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("knownDeviceList"));
}
}
}
}
这是我的 ObservableCollection 类:
public class DisplayedDevice : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public int Id { get; set; }
public string Name { get; set; }
public string State { get; set; }
public string StateShown { get; set; }
public string deviceImage { get; set; }
public string Color { get; set; }
public string PowerStateColor { get; set; }
public string DeviceImageColor { get; set; }
public string DeviceImage
{
get
{
return deviceImage;
}
set
{
deviceImage = value;
OnPropertyChanged();
}
}
}
这是xaml:
<ListView ItemsSource="{Binding knownDeviceList}" SelectionMode="None" RowHeight="90" ItemTapped="device_Clicked" x:Name="MyListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<AbsoluteLayout HeightRequest="70" Margin="20,10,20,10">
<StackLayout Opacity="0.3" BackgroundColor="White"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All" />
<StackLayout AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="70" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding Name}" Margin="0,3,0,0"
FontAttributes="Bold" FontSize="24" TextColor="White" />
<Label Grid.Row="1" Grid.Column="1" Text="{Binding StateShown}" FontSize="18" TextColor="White" />
<!-- <Image Source="power" Grid.RowSpan="2" Grid.Column="2" Margin="5" /> -->
<controls:IconView x:Name="btnPower" Source="power" Grid.RowSpan="2" Grid.Column="2" Margin="5"
Foreground="{Binding PowerStateColor}">
<controls:IconView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.cmdTogglePower, Source={x:Reference MyListView}}" CommandParameter="{Binding Id}" />
</controls:IconView.GestureRecognizers>
</controls:IconView>
</Grid>
</StackLayout>
</AbsoluteLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
现在我期望发生的是,当我单击 IconView 时,我更改了 IconView 颜色和带有 StateShown 绑定的标签。但是当我点击 IconView 时没有任何变化!
我究竟做错了什么?
解决方案
您可以使用 MVVMHelpers NuGet 包并将 NuGet 中的 ObservableObject 类直接实现到 DisplayedDevice 类,并且您需要使用私有变量的引用来制作所有属性。
public class DisplayedDevice: ObservableObject
{
string _textField = string.Empty;
public string TextField
{
get => _textField;
set => SetProperty(ref _textField, value);
}
bool _isBarChartVisible = false;
public bool IsBarChartVisible
{
get => _isBarChartVisible;
set => SetProperty(ref _isBarChartVisible, value);
}
}
}
每个公共财产都应该由相同类型的私有财产支持。这很重要,因此任何属性的任何更改都将使用 INotifyPropertyChanged 反映在 UI 上
推荐阅读
- linux - epoll的EPOLLEXCLUSIVE可以同时触发同一个socket上的多个读取吗?
- php - PHP 致命错误:未捕获的 GuzzleHttp\Exception\ClientException
- r - R 面板数据中变量的计数/绘图随时间变化
- sql - 仅选择顶部父表行及其所有子表行
- r - 如何使用一个值作为 Y-max 和另一个作为填充 ggplot
- c# - IDisposable接口确认
- python-3.x - 如何缓存 celery 应用程序处理的结果
- here-api - Here Maps - 自动完成建议
- php - 如何使用wordpress wp_remote_post将客户端multipart/formdata发布到.net core rest API?
- python - 美汤如何选择某类下的所有数据