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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:01:55