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

如何为SQLite查询结果添加行号列并解决列表更新问题

简化实现方案

方案1:直接在XAML绑定中生成行号(最简方案)

不需要在后台处理行号逻辑,直接通过DataGrid的AlternationIndex绑定实现排名列,完全避免集合更新问题:

步骤1:修改XAML的DataGrid配置

添加行号列,并设置AlternationCount(值设为大于最大可能的行数即可):

<DataGrid x:Name="Datagrid" AlternationCount="100">
    <DataGrid.Columns>
        <!-- 排名列 -->
        <DataGridTextColumn Header="排名" 
                            Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource AncestorType=DataGridRow}, Converter={StaticResource IndexPlusOneConverter}}"/>
        <!-- 其他业务列 -->
        <DataGridTextColumn Header="队名" Binding="{Binding Team_Naam}"/>
        <DataGridTextColumn Header="积分" Binding="{Binding PuntenVoor}"/>
    </DataGrid.Columns>
</DataGrid>

步骤2:创建索引转排名的转换器

新建一个转换器类,将AlternationIndex(从0开始)转为排名(加1):

public class IndexPlusOneConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is int index ? index + 1 : value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

记得在XAML的资源中声明这个转换器:

<Page.Resources>
    <local:IndexPlusOneConverter x:Key="IndexPlusOneConverter"/>
</Page.Resources>

步骤3:简化后台代码

删除原代码中的IEnumerable<object> resultaat;变量,直接将results作为DataGrid的数据源:

// 调整OnNavigatedTo方法
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    LoadData();
    WireUpDropdown();
    Datagrid.ItemsSource = results; // 直接绑定原集合
}

// 调整LoadStand方法,无需生成匿名类型集合
private void LoadStand()
{
    string sql = "SELECT * FROM Team WHERE KlasseId = @KlasseId ORDER BY PuntenVoor DESC LIMIT 10";
    Dictionary<string, object> parameters = new Dictionary<string, object>
    {
        { "@KlasseId", klasseDropDown.SelectedValue}
    };
    var spelerlijst = SqliteDataAccess.LoadData<TeamModel>(sql, parameters);
    
    results.Clear();
    spelerlijst.ForEach(results.Add);
}

每次下拉框切换时,results的变更会自动通知DataGrid刷新,行号由XAML绑定自动生成。


方案2:创建带排名的ViewModel(适合复杂排名逻辑)

如果需要处理并列排名等复杂逻辑,可以创建专门的ViewModel来封装排名和球队数据:

步骤1:定义ViewModel

public class TeamWithRankViewModel
{
    public int Rank { get; set; }
    public TeamModel Team { get; set; }
}

步骤2:替换原集合变量

// 替换原有的results和resultaat
ObservableCollection<TeamWithRankViewModel> rankedTeams = new ObservableCollection<TeamWithRankViewModel>();

步骤3:修改后台绑定和加载逻辑

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    LoadData();
    WireUpDropdown();
    Datagrid.ItemsSource = rankedTeams;
}

private void LoadStand()
{
    string sql = "SELECT * FROM Team WHERE KlasseId = @KlasseId ORDER BY PuntenVoor DESC LIMIT 10";
    Dictionary<string, object> parameters = new Dictionary<string, object>
    {
        { "@KlasseId", klasseDropDown.SelectedValue}
    };
    var spelerlijst = SqliteDataAccess.LoadData<TeamModel>(sql, parameters);
    
    rankedTeams.Clear();
    // 生成排名,如需并列逻辑可在此处修改
    for (int i = 0; i < spelerlijst.Count; i++)
    {
        rankedTeams.Add(new TeamWithRankViewModel
        {
            Rank = i + 1,
            Team = spelerlijst[i]
        });
    }
}

步骤4:修改XAML绑定

<DataGridTextColumn Header="排名" Binding="{Binding Rank}"/>
<DataGridTextColumn Header="队名" Binding="{Binding Team.Team_Naam}"/>
<DataGridTextColumn Header="积分" Binding="{Binding Team.PuntenVoor}"/>

原代码问题说明

  1. IEnumerable<object>是不可变集合,重新赋值时无法触发UI自动更新,且无法清空;
  2. LINQ查询中使用i++会因延迟执行导致行号不符合预期,正确做法是使用Select((item, index) => ...)获取索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 23:55:35