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

.NET MAUI修改ObservableCollection项属性后CollectionView未刷新

.NET MAUI CollectionView绑定项属性修改不刷新问题

问题现象

  • 将ObservableCollection实例绑定到CollectionView控件后,对集合执行新增、删除项操作时,CollectionView可正常响应刷新
  • 通过代码修改集合内单个项的属性值时,界面不会同步展示更新后的内容
  • 项目已引入CommunityToolkit.Mvvm库,预期工具包自动完成属性变更通知逻辑,但实际未生效
  • 项目公开仓库地址:TestCollectionBinding

现有实现代码

1. Views/MyItem.cs

namespace TestCollectionBinding.Views;

public class MyItem
{
  public string Name { get; set; }
  public string Device { get; set; }
}

2. ViewModels/MainPageViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Collections.ObservableCollection;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using TestCollectionBinding.Views;

namespace TestCollectionBinding.ViewModels;

public partial class MainPageViewModel : ObservableObject
{
  [ObservableProperty]
  public ObservableCollection<MyItem> myItems = new()
  {
    new MyItem
    {
      Name = "Heart Rate Monitor",
      Device = "12:12:12:12:AB"
    },

    new MyItem
    {
      Name = "Cadence",
      Device = "34:34:34:34:CD"
    }
  };

  public ICommand ChangeCommand => new Command(ChangeControl);
  public void ChangeControl()
  {
    foreach (MyItem q in MyItems)
    {
      q.Device = "***********";
    }
    Console.WriteLine($"Change device");
  }
}

3. MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:TestCollectionBinding.ViewModels"
             x:Class="TestCollectionBinding.MainPage">

  <ContentPage.BindingContext>
    <local:MainPageViewModel />
  </ContentPage.BindingContext>

  <StackLayout>
    <Label Text="Items" 
           FontSize="20"
           TextColor="Blue"/>

    <CollectionView x:Name="MyItemsList"
                    ItemsSource="{Binding MyItems}">
      <CollectionView.ItemTemplate>
        <DataTemplate>
          <Grid
            Margin="10, 0, 10, 10"
            ColumnDefinitions="200, 200">
            <Label Grid.Column="0" 
                   Text="{Binding Name}" 
                   FontSize="20"/>

            <Label Grid.Column="1" 
                   Text="{Binding Device}" 
                   FontSize="20"/>            
          </Grid>
   
        </DataTemplate>
      </CollectionView.ItemTemplate>
    </CollectionView>

    <Button
      Text="Change device names"
      FontFamily="20"
      WidthRequest="150"
      Command="{Binding ChangeCommand}" />
    
  </StackLayout>

</ContentPage>

运行表现

页面初始加载时可正常展示2条列表数据,点击「Change device names」按钮触发命令后,代码已将所有MyItem实例的Device属性修改为***********,但CollectionView未同步更新显示内容,预期界面可实时响应属性变更刷新。

问题原因

ObservableCollection仅在集合本身发生变更(新增、删除、替换项、重置集合)时触发CollectionChanged通知,不会监控集合内单个项的属性变化。要让项属性修改触发界面刷新,集合内的元素类必须自身实现INotifyPropertyChanged接口,在属性值变更时发出PropertyChanged通知。
当前代码中MyItem是普通POCO类,未实现属性变更通知逻辑。CommunityToolkit.Mvvm不会自动为普通类注入通知逻辑,只有继承工具包提供的基类(如ObservableObject)、并配合源生成器标注的类,才会自动生成属性变更通知代码。

修复方案

修改MyItem类,继承CommunityToolkit.Mvvm.ComponentModel.ObservableObject,给需要触发变更通知的属性加上[ObservableProperty]标注。注意工具包的源生成器要求类必须声明为partial,被标注的成员为私有字段,采用小驼峰命名,源生成器会自动生成对应大驼峰命名的公开属性,和原有业务代码的属性命名完全兼容,不需要修改其他业务逻辑。

修改后的MyItem.cs

using CommunityToolkit.Mvvm.ComponentModel;

namespace TestCollectionBinding.Views;

public partial class MyItem : ObservableObject
{
  [ObservableProperty]
  private string name;

  [ObservableProperty]
  private string device;
}

注意:现有ViewModel代码中ObservableCollection的命名空间引用存在笔误,正确命名空间为System.Collections.ObjectModel,需要修正using引用,否则会出现编译错误。

修改完成后重新编译运行,点击按钮修改项属性时界面就会正常同步刷新。

内容的提问来源于stack exchange,提问作者gfmoore

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:01:06