如何在Blazor中实现按钮触发的待办事项按日期排序?
Blazor待办事项按日期排序功能修复方案
问题描述
我是一名.NET新手,需要为我的待办事项列表实现按日期排序的功能。我编写了如下代码,但排序功能无法生效,希望通过按钮触发排序。我认为
@foreach是问题所在,已经尝试过多种改写方式,但都没有效果。我在谷歌上搜索了各类资料,但都无法适配我的现有代码。
原始代码:
@page "/todo" @using System.Linq <PageTitle>Todo</PageTitle> <h2>Progress bar</h2> <label for="file">Progress:</label> <progress id="file" value=@PocetSplnenych max=@CelkovyPocet></progress> <h1>Todo (@todos.Count(todo => !todo.IsDone))</h1> <ul> @foreach (var todo in todos) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> <input @bind="todo.date" /> <input @bind="todo.Priority" /> </li> } </ul> <h3>Hotové (@todos2.Count(todo => !todo.IsDone))</h3> <ul> @foreach (var todo in todos2) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> <input @bind="todo.date" /> <input @bind="todo.Priority" /> </li> } </ul> <input placeholder="Úkol" @bind="newTodo" /> <input type="date" placeholder="Select a date" @bind="date" /> <input placeholder="Jaká je priorita?" @bind="newPriority" /> <button @onclick="AddTodo">přidat</button> <button @onclick="Delete">smazat</button> <button @onclick="Move">přesunout</button> <button @onclick="Sort">Seřadit</button> @code { private List<TodoItem> todos = new(); private string? newTodo; private DateOnly date; private string? newPriority; private void Sort() { foreach (var received in todos.OrderBy(a => a.date)) { @received.date } } }
问题分析
你的Sort方法没有实际修改绑定的数据源:
- 仅遍历排序后的结果,未更新
todos集合的实际顺序 - 代码块中使用
@received.date是无效的Razor语法,无法触发界面更新 - Blazor的UI渲染依赖组件状态变化,未修改数据源的情况下,界面不会自动刷新
修复方案
1. 修正Sort方法,更新数据源
将排序后的结果重新赋值给todos集合,Blazor会自动检测到集合变化并重新渲染界面:
private void Sort() { // 用OrderBy排序后转成List,重新赋值给todos todos = todos.OrderBy(a => a.date).ToList(); }
2. 可选:手动触发状态更新(按需)
如果遇到界面未自动刷新的情况,可以在排序后手动通知组件状态变化:
private void Sort() { todos = todos.OrderBy(a => a.date).ToList(); StateHasChanged(); // 手动触发UI渲染,多数场景下可省略 }
3. 补充缺失的代码(确保完整运行)
原代码缺少todos2定义、TodoItem类及部分方法实现,补充后完整代码如下:
@page "/todo" @using System.Linq <PageTitle>Todo</PageTitle> <h2>Progress bar</h2> <label for="file">Progress:</label> <progress id="file" value=@PocetSplnenych max=@CelkovyPocet></progress> <h1>Todo (@todos.Count(todo => !todo.IsDone))</h1> <ul> @foreach (var todo in todos) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> <input @bind="todo.date" /> <input @bind="todo.Priority" /> </li> } </ul> <h3>Hotové (@todos2.Count(todo => !todo.IsDone))</h3> <ul> @foreach (var todo in todos2) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> <input @bind="todo.date" /> <input @bind="todo.Priority" /> </li> } </ul> <input placeholder="Úkol" @bind="newTodo" /> <input type="date" placeholder="Select a date" @bind="date" /> <input placeholder="Jaká je priorita?" @bind="newPriority" /> <button @onclick="AddTodo">přidat</button> <button @onclick="Delete">smazat</button> <button @onclick="Move">přesunout</button> <button @onclick="Sort">Seřadit</button> @code { private List<TodoItem> todos = new(); private List<TodoItem> todos2 = new(); private string? newTodo; private DateOnly date; private string? newPriority; private void AddTodo() { if (!string.IsNullOrWhiteSpace(newTodo)) { todos.Add(new TodoItem { Title = newTodo, date = date, Priority = newPriority }); newTodo = null; newPriority = null; } } private void Delete() { todos.RemoveAll(t => t.IsDone); todos2.RemoveAll(t => t.IsDone); } private void Move() { var doneItems = todos.Where(t => t.IsDone).ToList(); todos.RemoveAll(t => t.IsDone); todos2.AddRange(doneItems); } private void Sort() { todos = todos.OrderBy(a => a.date).ToList(); } public class TodoItem { public bool IsDone { get; set; } public string? Title { get; set; } public DateOnly date { get; set; } public string? Priority { get; set; } } private int PocetSplnenych => todos.Count(t => t.IsDone) + todos2.Count(t => t.IsDone); private int CelkovyPocet => todos.Count + todos2.Count; }
关键说明
OrderBy返回的是IEnumerable<T>,必须通过ToList()转换为List<TodoItem>才能重新赋值给todos@foreach本身没有问题,只要数据源顺序改变,Blazor会自动重新渲染列表- 补充的代码确保了组件的完整性,可直接运行测试排序功能
内容的提问来源于stack exchange,提问作者Pavel Chřibek
相关产品推荐
相关产品推荐

