Avalonia绑定ObservableCollectionExtended到DataGrid更新仅显示首项问题
问题:Avalonia + FluentAvalonia DataGrid 数据更新异常
我正在学习Avalonia框架,使用FluentAvalonia NuGet包引入WinUI控件(包含DataGrid)。将DataGrid的Items属性绑定到ObservableCollectionExtended类型的SystemInfoEntries属性,相关代码如下:
DataGrid的XAML代码
<DataGrid AutoGenerateColumns="False" Items="{Binding SystemInfoEntries}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" CanUserResizeColumns="True" CanUserSortColumns="True"> <DataGrid.Columns> <DataGridTextColumn Header="Name" Width="*" Binding="{Binding Name}" IsReadOnly="True"/> <DataGridTextColumn Header="Value" Width="*" Binding="{Binding Value}" IsReadOnly="True"/> </DataGrid.Columns> </DataGrid>
SystemInfoEntries属性定义
private IObservableCollection<SystemInfoEntry> _systemInfoEntries; public IObservableCollection<SystemInfoEntry> SystemInfoEntries { get => _systemInfoEntries; set => this.RaiseAndSetIfChanged(ref _systemInfoEntries, value); }
SystemInfoEntry模型
public class SystemInfoEntry : INotifyPropertyChanged { private string _value; private string _name; public string Name { get => _name; set => SetField(ref _name, value); } public string Value { get => _value; set => SetField(ref _value, value); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer<T>.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } }
异常现象
ViewModel构造时用占位项初始化集合,DataGrid可正常显示该占位项;但后续清空集合并添加10个新项时,DataGrid仅显示第一个新项。若初始化时不添加占位项,直接填充数据则显示正常。
问题分析与解决
核心原因:FluentAvalonia的DataGrid在处理
ObservableCollectionExtended的批量更新时存在UI同步逻辑缺陷——当集合先有初始项,后续执行Clear()再批量添加元素时,DataGrid对集合变更通知的处理出现异常,仅能识别到第一个新增元素的变更事件。具体来说,Clear()触发的Reset通知可能干扰了后续Add操作的事件捕获,导致UI未同步全部新增数据。解决办法:
- 替换集合实例:清空并添加新数据时,直接创建新的
ObservableCollectionExtended实例赋值给SystemInfoEntries属性,利用属性变更通知触发DataGrid完全刷新:// 替代Clear()+AddRange的操作 SystemInfoEntries = new ObservableCollectionExtended<SystemInfoEntry>(newItems); - 手动触发集合刷新:如果必须复用原集合,在批量添加完成后调用
ObservableCollectionExtended自带的Refresh()方法,强制同步UI:SystemInfoEntries.Clear(); SystemInfoEntries.AddRange(newItems); SystemInfoEntries.Refresh(); - 改用原生集合类型:若不需要
ObservableCollectionExtended的额外功能,替换为Avalonia原生的ObservableCollection<T>,其集合变更通知逻辑更稳定,能避免此类兼容性问题。
- 替换集合实例:清空并添加新数据时,直接创建新的
内容的提问来源于stack exchange,提问作者Codehack
相关产品推荐
相关产品推荐

