允许排序
This commit is contained in:
@@ -22,6 +22,24 @@ namespace TodoList.Models
|
|||||||
Failed
|
Failed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum SortBy
|
||||||
|
{
|
||||||
|
[Description("创建时间")]
|
||||||
|
CreatedAt,
|
||||||
|
[Description("完成时间")]
|
||||||
|
CompletedAt,
|
||||||
|
[Description("优先级")]
|
||||||
|
Priority
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SortOrder
|
||||||
|
{
|
||||||
|
[Description("升序")]
|
||||||
|
Ascending,
|
||||||
|
[Description("降序")]
|
||||||
|
Descending
|
||||||
|
}
|
||||||
|
|
||||||
public partial class TodoItem : ObservableObject
|
public partial class TodoItem : ObservableObject
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
@@ -40,6 +58,9 @@ namespace TodoList.Models
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private DateTime createdAt = DateTime.Now;
|
private DateTime createdAt = DateTime.Now;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private DateTime? completedAt;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private SyncStatus syncStatus = SyncStatus.Pending;
|
private SyncStatus syncStatus = SyncStatus.Pending;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||||
<Version>1.0.18</Version>
|
<Version>1.0.21</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -38,4 +38,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ namespace TodoList.ViewModels
|
|||||||
[NotifyPropertyChangedFor(nameof(FullShortcut))]
|
[NotifyPropertyChangedFor(nameof(FullShortcut))]
|
||||||
private string shortcutModifiers;
|
private string shortcutModifiers;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private SortBy sortBy = SortBy.Priority;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private Models.SortOrder sortOrder = Models.SortOrder.Descending;
|
||||||
|
|
||||||
public string AppVersion => System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "1.0.0";
|
public string AppVersion => System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "1.0.0";
|
||||||
|
|
||||||
public string FullShortcut
|
public string FullShortcut
|
||||||
@@ -90,6 +96,16 @@ namespace TodoList.ViewModels
|
|||||||
await LoadTasksAsync();
|
await LoadTasksAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async partial void OnSortByChanged(SortBy value)
|
||||||
|
{
|
||||||
|
await LoadTasksAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
async partial void OnSortOrderChanged(Models.SortOrder value)
|
||||||
|
{
|
||||||
|
await LoadTasksAsync();
|
||||||
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private async Task AddTaskAsync()
|
private async Task AddTaskAsync()
|
||||||
{
|
{
|
||||||
@@ -118,12 +134,26 @@ namespace TodoList.ViewModels
|
|||||||
? allTasks
|
? allTasks
|
||||||
: allTasks.Where(t => !t.IsCompleted).ToList();
|
: allTasks.Where(t => !t.IsCompleted).ToList();
|
||||||
|
|
||||||
// Sort: Uncompleted first, then by priority (High -> Low), then date
|
IOrderedEnumerable<TodoItem> sorted;
|
||||||
var sorted = filtered
|
|
||||||
.OrderBy(t => t.IsCompleted)
|
if (SortBy == SortBy.Priority)
|
||||||
.ThenByDescending(t => t.Priority)
|
{
|
||||||
.ThenByDescending(t => t.CreatedAt)
|
sorted = SortOrder == Models.SortOrder.Ascending
|
||||||
.ToList();
|
? filtered.OrderBy(t => t.Priority).ThenBy(t => t.CreatedAt)
|
||||||
|
: filtered.OrderByDescending(t => t.Priority).ThenBy(t => t.CreatedAt);
|
||||||
|
}
|
||||||
|
else if (SortBy == SortBy.CreatedAt)
|
||||||
|
{
|
||||||
|
sorted = SortOrder == Models.SortOrder.Ascending
|
||||||
|
? filtered.OrderBy(t => t.CreatedAt)
|
||||||
|
: filtered.OrderByDescending(t => t.CreatedAt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sorted = SortOrder == Models.SortOrder.Ascending
|
||||||
|
? filtered.OrderBy(t => t.CompletedAt).ThenBy(t => t.CreatedAt)
|
||||||
|
: filtered.OrderByDescending(t => t.CompletedAt).ThenBy(t => t.CreatedAt);
|
||||||
|
}
|
||||||
|
|
||||||
Tasks.Clear();
|
Tasks.Clear();
|
||||||
foreach (var t in sorted)
|
foreach (var t in sorted)
|
||||||
@@ -136,13 +166,19 @@ namespace TodoList.ViewModels
|
|||||||
private async Task ToggleCompleteAsync(TodoItem item)
|
private async Task ToggleCompleteAsync(TodoItem item)
|
||||||
{
|
{
|
||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
// item.IsCompleted is already toggled by UI binding before this command if TwoWay binding
|
|
||||||
// But usually CheckBox command parameter is the item.
|
|
||||||
// Let's assume the binding updates the property.
|
|
||||||
|
|
||||||
item.SyncStatus = SyncStatus.Pending; // Mark as pending sync
|
if (item.IsCompleted)
|
||||||
|
{
|
||||||
|
item.CompletedAt = DateTime.Now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.CompletedAt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.SyncStatus = SyncStatus.Pending;
|
||||||
await _dataService.SaveTaskAsync(item);
|
await _dataService.SaveTaskAsync(item);
|
||||||
await LoadTasksAsync(); // Refresh list to apply filter
|
await LoadTasksAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
|
|||||||
@@ -22,6 +22,22 @@
|
|||||||
</ObjectDataProvider.MethodParameters>
|
</ObjectDataProvider.MethodParameters>
|
||||||
</ObjectDataProvider>
|
</ObjectDataProvider>
|
||||||
|
|
||||||
|
<ObjectDataProvider x:Key="SortByEnum" MethodName="GetValues"
|
||||||
|
ObjectType="{x:Type sys:Enum}"
|
||||||
|
xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||||
|
<ObjectDataProvider.MethodParameters>
|
||||||
|
<x:Type TypeName="models:SortBy"/>
|
||||||
|
</ObjectDataProvider.MethodParameters>
|
||||||
|
</ObjectDataProvider>
|
||||||
|
|
||||||
|
<ObjectDataProvider x:Key="SortOrderEnum" MethodName="GetValues"
|
||||||
|
ObjectType="{x:Type sys:Enum}"
|
||||||
|
xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||||
|
<ObjectDataProvider.MethodParameters>
|
||||||
|
<x:Type TypeName="models:SortOrder"/>
|
||||||
|
</ObjectDataProvider.MethodParameters>
|
||||||
|
</ObjectDataProvider>
|
||||||
|
|
||||||
<Style x:Key="ModernButton" TargetType="Button">
|
<Style x:Key="ModernButton" TargetType="Button">
|
||||||
<Setter Property="Background" Value="#007AFF"/>
|
<Setter Property="Background" Value="#007AFF"/>
|
||||||
<Setter Property="Foreground" Value="White"/>
|
<Setter Property="Foreground" Value="White"/>
|
||||||
@@ -62,11 +78,32 @@
|
|||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBlock Text="我的待办" FontSize="24" FontWeight="Bold" Foreground="#333"/>
|
<StackPanel Grid.Column="1" Orientation="Horizontal" Margin="10,0,15,0" VerticalAlignment="Center">
|
||||||
|
<ComboBox ItemsSource="{Binding Source={StaticResource SortByEnum}}"
|
||||||
|
SelectedItem="{Binding SortBy}"
|
||||||
|
Width="90" VerticalContentAlignment="Center" Margin="0,0,5,0">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding Converter={StaticResource EnumDescConverter}}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
<ComboBox ItemsSource="{Binding Source={StaticResource SortOrderEnum}}"
|
||||||
|
SelectedItem="{Binding SortOrder}"
|
||||||
|
Width="60" VerticalContentAlignment="Center">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding Converter={StaticResource EnumDescConverter}}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<Button Grid.Column="1" Content="设置快捷键"
|
<Button Grid.Column="2" Content="设置快捷键"
|
||||||
Command="{Binding OpenSettingsCommand}"
|
Command="{Binding OpenSettingsCommand}"
|
||||||
Background="Transparent" Foreground="#007AFF" Margin="0,0,15,0">
|
Background="Transparent" Foreground="#007AFF" Margin="0,0,15,0">
|
||||||
<Button.Template>
|
<Button.Template>
|
||||||
@@ -76,7 +113,7 @@
|
|||||||
</Button.Template>
|
</Button.Template>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<CheckBox Grid.Column="2" Content="显示已完成"
|
<CheckBox Grid.Column="3" Content="显示已完成"
|
||||||
IsChecked="{Binding ShowCompleted}"
|
IsChecked="{Binding ShowCompleted}"
|
||||||
VerticalAlignment="Center" Foreground="#555"/>
|
VerticalAlignment="Center" Foreground="#555"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
#define MyAppName "TodoList"
|
#define MyAppName "TodoList"
|
||||||
#define MyAppVersion "1.0.18"
|
#define MyAppVersion "1.0.21"
|
||||||
#define MyAppPublisher "ShaoHua"
|
#define MyAppPublisher "ShaoHua"
|
||||||
#define MyAppURL "https://git.we965.cn/Tools/TodoList"
|
#define MyAppURL "https://git.we965.cn/Tools/TodoList"
|
||||||
#define MyAppExeName "TodoList.exe"
|
#define MyAppExeName "TodoList.exe"
|
||||||
|
|||||||
Reference in New Issue
Block a user