You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 05:55:19