如何为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}"/>
原代码问题说明
IEnumerable<object>是不可变集合,重新赋值时无法触发UI自动更新,且无法清空;- LINQ查询中使用
i++会因延迟执行导致行号不符合预期,正确做法是使用Select((item, index) => ...)获取索引。
内容的提问来源于stack exchange,提问作者Rob0t
相关产品推荐
相关产品推荐

