.NET Maui中如何展示ObservableCollection内容?代码问题求助
问题排查与解决
核心问题分析
你的代码存在三个关键问题,导致List数据无法正常展示:
1. 集合属性未正确更新
SortResults方法里创建了局部变量GameResultsToShow,而非给类的同名属性赋值。这意味着绑定的目标集合根本没接收到排序后的数据。
2. 数据绑定路径错误
XAML中TextCell绑定的GameResult是实体类本身,界面无法直接展示一个对象,必须绑定到GameResult的具体字段(比如points、Time)。
3. 缺失属性变更通知(MVVM场景)
如果你的ViewModel没实现INotifyPropertyChanged接口,就算更新了GameResultsToShow属性,界面也不会收到更新通知。
修正后的代码
后台代码(Code-behind)
using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; // 若为ViewModel类,需实现INotifyPropertyChanged接口 public class YourViewModel : INotifyPropertyChanged { private ObservableCollection<GameResult> _gameResultsToShow; public ObservableCollection<GameResult> GameResultsToShow { get => _gameResultsToShow; set { _gameResultsToShow = value; OnPropertyChanged(nameof(GameResultsToShow)); } } // 原始数据集 private List<GameResult> GameResults { get; set; } private GameOption gameOption { get; set; } public YourViewModel() { GameResultsToShow = new ObservableCollection<GameResult>(); GameResults = new List<GameResult>(); gameOption = new GameOption(); } public void SortResults() { IOrderedEnumerable<GameResult> sortedQuery; // 先过滤符合条件的数据,再排序 var filteredResults = GameResults.Where(x => x.gameOption.gameLevel == gameOption.gameLevel && x.gameOption.gameType == gameOption.gameType); if (gameOption.gameType == GameType.Time) sortedQuery = filteredResults.OrderBy(x => x.points); else sortedQuery = filteredResults.OrderBy(x => x.Time); // 清空原有集合并添加新数据,比重新创建集合更高效 GameResultsToShow.Clear(); foreach (var result in sortedQuery) { GameResultsToShow.Add(result); } } // INotifyPropertyChanged接口实现 public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } // 实体类示例 public class GameResult { public GameOption gameOption { get; set; } public int points { get; set; } public TimeSpan Time { get; set; } // 自定义显示文本,方便界面绑定 public string DisplayText => $"分数: {points} | 用时: {Time:mm\\:ss}"; } public enum GameType { Time, Score } public class GameOption { public int gameLevel { get; set; } public GameType gameType { get; set; } }
XAML代码
<CollectionView ItemsSource="{Binding GameResultsToShow}" BackgroundColor="PapayaWhip" Margin="10" Grid.Row="5" Grid.ColumnSpan="3" HorizontalOptions="Center"> <CollectionView.ItemTemplate> <DataTemplate> <!-- 绑定到自定义的显示文本属性 --> <TextCell Text="{Binding DisplayText}" /> <!-- 也可以分开显示单个属性 --> <!-- <Label Text="{Binding points}" /> <Label Text="{Binding Time}" /> --> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
额外注意事项
- 若在页面Code-behind直接绑定,需在构造函数中设置
BindingContext = this;。 - 使用
Clear()+Add()更新集合,比重新创建ObservableCollection更高效,能减少界面重复渲染。 - 确保
GameResults原始数据集已正确填充数据,否则过滤后会得到空集合。
内容的提问来源于stack exchange,提问作者wojtek
相关产品推荐
相关产品推荐

