ObservableCollection对象属性更新后UI未同步的技术求助
问题描述
将ObservableCollection<ExerciseModel>与CollectionView绑定后,向集合添加新对象时UI能正常更新,但修改集合内对象的属性(比如Reps)时,UI无法同步变化。
相关代码
XAML代码
<CollectionView ItemsSource="{Binding LeftExercises}"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="models:ExerciseModel"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="3*" /> <ColumnDefinition Width="4*" /> <ColumnDefinition Width="4*" /> </Grid.ColumnDefinitions> <Label Grid.Column="0" Grid.Row="0" Text="{Binding SetNumber}" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="Black" FontSize="Medium" /> <Label Grid.Column="1" Grid.Row="0" Text="{Binding Weight}" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="Black" FontSize="Medium" /> <Label Grid.Column="2" Grid.Row="0" Text="{Binding Reps}" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="Black" FontSize="Medium" /> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
ViewModel集合定义
private ObservableCollection<ExerciseModel> _leftExercises; public ObservableCollection<ExerciseModel> LeftExercises { get => _leftExercises; set { if (_leftExercises != value) { _leftExercises = value; OnPropertyChanged(nameof(LeftExercises)); } } }
ExerciseModel定义
public class ExerciseModel { public int SetNumber { get; set; } public decimal Weight { get; set; } public int Reps { get; set; } public ExerciseType ExerciseType { get; set; } public Side Side { get; set; } }
属性更新命令
private Command _dummyLeftIncreaseRepsCommand; public Command dummyLeftIncreaseRepsCommand { get { return _dummyLeftIncreaseRepsCommand ??= new Command(() => { ExerciseModel lastObj = LeftExercises.Last(x => x.Side == SharedVM.ActiveSide); lastObj.Reps += 1; }); } }
问题原因
ObservableCollection仅在集合元素数量变化(添加、删除、替换元素)时触发UI更新,不会监听集合内单个对象的属性变更。你的ExerciseModel未实现属性变更通知机制,导致修改属性时UI无法感知变化。
解决方案
让ExerciseModel实现INotifyPropertyChanged接口,在属性setter中触发PropertyChanged事件,这样属性值变更时就能通知UI更新。
修改后的ExerciseModel代码:
public class ExerciseModel : INotifyPropertyChanged { private int _setNumber; private decimal _weight; private int _reps; private ExerciseType _exerciseType; private Side _side; public int SetNumber { get => _setNumber; set { if (_setNumber != value) { _setNumber = value; OnPropertyChanged(nameof(SetNumber)); } } } public decimal Weight { get => _weight; set { if (_weight != value) { _weight = value; OnPropertyChanged(nameof(Weight)); } } } public int Reps { get => _reps; set { if (_reps != value) { _reps = value; OnPropertyChanged(nameof(Reps)); } } } public ExerciseType ExerciseType { get => _exerciseType; set { if (_exerciseType != value) { _exerciseType = value; OnPropertyChanged(nameof(ExerciseType)); } } } public Side Side { get => _side; set { if (_side != value) { _side = value; OnPropertyChanged(nameof(Side)); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
补充说明
- 若项目中已有实现
INotifyPropertyChanged的基类(如BaseViewModel),可让ExerciseModel直接继承该基类,减少重复代码。 - 当前ViewModel中
LeftExercises属性的OnPropertyChanged触发逻辑是正确的,无需修改。
内容的提问来源于stack exchange,提问作者RMR
相关产品推荐
相关产品推荐

