mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-21 09:45:48 +08:00
新增窗口
This commit is contained in:
@@ -17,9 +17,11 @@ using BetterGenshinImpact.Service.Notification;
|
||||
using BetterGenshinImpact.Service.Notifier;
|
||||
using BetterGenshinImpact.View;
|
||||
using BetterGenshinImpact.View.Pages;
|
||||
using BetterGenshinImpact.View.Windows;
|
||||
using BetterGenshinImpact.ViewModel;
|
||||
using BetterGenshinImpact.ViewModel.Pages;
|
||||
using BetterGenshinImpact.ViewModel.Pages.View;
|
||||
using BetterGenshinImpact.ViewModel.Windows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -114,6 +116,8 @@ public partial class App : Application
|
||||
services.AddView<SchedulerPage, SchedulerViewModel>();
|
||||
services.AddView<GearTaskListPage, GearTaskListPageViewModel>();
|
||||
services.AddView<GearTriggerPage, GearTriggerPageViewModel>();
|
||||
services.AddTransient<TaskDefinitionEditWindow>();
|
||||
services.AddTransient<TaskDefinitionEditWindowViewModel>();
|
||||
|
||||
|
||||
// 一条龙 ViewModels
|
||||
|
||||
@@ -134,13 +134,6 @@
|
||||
Content="新建"
|
||||
Icon="{ui:SymbolIcon Add24}"
|
||||
Margin="0,0,4,0" />
|
||||
<ui:Button Command="{Binding SaveToJsonCommand}"
|
||||
Content="保存"
|
||||
Icon="{ui:SymbolIcon Save24}"
|
||||
Margin="0,0,4,0" />
|
||||
<ui:Button Command="{Binding LoadFromJsonCommand}"
|
||||
Content="加载"
|
||||
Icon="{ui:SymbolIcon Open24}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 任务定义列表 -->
|
||||
@@ -159,6 +152,20 @@
|
||||
dd:DragDrop.DropHandler="{Binding}"
|
||||
dd:DragDrop.UseDefaultDragAdorner="True"
|
||||
Padding="4">
|
||||
<ListBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="新增任务定义"
|
||||
Command="{Binding AddTaskDefinitionCommand}"
|
||||
Icon="{ui:SymbolIcon Add24}" />
|
||||
<Separator />
|
||||
<MenuItem Header="编辑选中项"
|
||||
Command="{Binding EditSelectedTaskDefinitionCommand}"
|
||||
Icon="{ui:SymbolIcon Edit24}" />
|
||||
<MenuItem Header="删除选中项"
|
||||
Command="{Binding DeleteSelectedTaskDefinitionCommand}"
|
||||
Icon="{ui:SymbolIcon Delete24}" />
|
||||
</ContextMenu>
|
||||
</ListBox.ContextMenu>
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<ui:FluentWindow x:Class="BetterGenshinImpact.View.Windows.TaskDefinitionEditWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
Width="450"
|
||||
Height="280"
|
||||
MinWidth="400"
|
||||
MinHeight="250"
|
||||
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
|
||||
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
FontFamily="{DynamicResource TextThemeFontFamily}"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
WindowStyle="SingleBorderWindow">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 内容部分 -->
|
||||
<Grid Grid.Row="1" Margin="12,12,12,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 名称输入 -->
|
||||
<StackPanel Grid.Row="0" Margin="5,5,5,15">
|
||||
<ui:TextBlock Text="名称:" Margin="0,0,0,5" FontWeight="Medium" />
|
||||
<ui:TextBox x:Name="NameTextBox"
|
||||
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
|
||||
PlaceholderText="请输入任务定义名称" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 描述输入 -->
|
||||
<StackPanel Grid.Row="1" Margin="5,0,5,5">
|
||||
<ui:TextBlock Text="描述:" Margin="0,0,0,5" FontWeight="Medium" />
|
||||
<ui:TextBox Text="{Binding Description, UpdateSourceTrigger=PropertyChanged}"
|
||||
PlaceholderText="请输入任务定义描述(可选)" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- 按钮部分 -->
|
||||
<Grid Grid.Row="2" Margin="12">
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<ui:Button Name="BtnOk"
|
||||
Margin="5"
|
||||
Appearance="Primary"
|
||||
Command="{Binding ConfirmCommand}"
|
||||
Content="确定"
|
||||
IsDefault="True"
|
||||
MinWidth="80" />
|
||||
<ui:Button Name="BtnCancel"
|
||||
Margin="5"
|
||||
Command="{Binding CancelCommand}"
|
||||
Content="取消"
|
||||
IsCancel="True"
|
||||
MinWidth="80" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<ui:TitleBar Name="MyTitleBar" Grid.Row="0" Title="任务定义编辑">
|
||||
<ui:TitleBar.Icon>
|
||||
<ui:ImageIcon Source="pack://application:,,,/Resources/Images/logo.png" />
|
||||
</ui:TitleBar.Icon>
|
||||
</ui:TitleBar>
|
||||
</Grid>
|
||||
</ui:FluentWindow>
|
||||
@@ -0,0 +1,42 @@
|
||||
using BetterGenshinImpact.Helpers.Ui;
|
||||
using BetterGenshinImpact.ViewModel.Windows;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace BetterGenshinImpact.View.Windows;
|
||||
|
||||
public partial class TaskDefinitionEditWindow : FluentWindow
|
||||
{
|
||||
public TaskDefinitionEditWindowViewModel ViewModel { get; }
|
||||
|
||||
public TaskDefinitionEditWindow(TaskDefinitionEditWindowViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
|
||||
// 设置窗口关闭事件
|
||||
ViewModel.RequestClose += (sender, result) =>
|
||||
{
|
||||
DialogResult = result;
|
||||
Close();
|
||||
};
|
||||
|
||||
// 窗口加载和初始化事件
|
||||
this.Loaded += TaskDefinitionEditWindowLoaded;
|
||||
this.SourceInitialized += TaskDefinitionEditWindow_SourceInitialized;
|
||||
}
|
||||
|
||||
private void TaskDefinitionEditWindow_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
// 应用与主窗口相同的背景主题
|
||||
WindowHelper.TryApplySystemBackdrop(this);
|
||||
}
|
||||
|
||||
private void TaskDefinitionEditWindowLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 自动聚焦到名称输入框
|
||||
NameTextBox.Focus();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,9 @@ using BetterGenshinImpact.Service;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Specialized;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
using BetterGenshinImpact.View.Windows;
|
||||
using BetterGenshinImpact.ViewModel.Windows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BetterGenshinImpact.ViewModel.Pages;
|
||||
|
||||
@@ -214,15 +217,31 @@ public partial class GearTaskListPageViewModel : ViewModel
|
||||
[RelayCommand]
|
||||
private async Task AddTaskDefinition()
|
||||
{
|
||||
var newTask = new GearTaskDefinitionViewModel($"新任务组 {TaskDefinitions.Count + 1}", "新创建的任务组");
|
||||
// 设置新任务的order为当前最大值+1
|
||||
newTask.Order = TaskDefinitions.Count > 0 ? TaskDefinitions.Max(t => t.Order) + 1 : 0;
|
||||
TaskDefinitions.Add(newTask);
|
||||
SetupTaskDefinitionPropertyChanged(newTask);
|
||||
SelectedTaskDefinition = newTask;
|
||||
var editViewModel = App.GetService<TaskDefinitionEditWindowViewModel>();
|
||||
if (editViewModel == null) return;
|
||||
|
||||
// 自动保存到文件
|
||||
await _storageService.SaveTaskDefinitionAsync(newTask);
|
||||
editViewModel.Name = $"新任务组{TaskDefinitions.Count + 1}";
|
||||
editViewModel.Description = "";
|
||||
|
||||
var editWindow = App.GetService<TaskDefinitionEditWindow>();
|
||||
if (editWindow == null) return;
|
||||
|
||||
editWindow.ViewModel.Name = editViewModel.Name;
|
||||
editWindow.ViewModel.Description = editViewModel.Description;
|
||||
editWindow.Owner = Application.Current.MainWindow;
|
||||
|
||||
if (editWindow.ShowDialog() == true)
|
||||
{
|
||||
var newTask = new GearTaskDefinitionViewModel(editWindow.ViewModel.Name, editWindow.ViewModel.Description);
|
||||
// 设置新任务的order为当前最大值+1
|
||||
newTask.Order = TaskDefinitions.Count > 0 ? TaskDefinitions.Max(t => t.Order) + 1 : 0;
|
||||
TaskDefinitions.Add(newTask);
|
||||
SetupTaskDefinitionPropertyChanged(newTask);
|
||||
SelectedTaskDefinition = newTask;
|
||||
|
||||
// 自动保存到文件
|
||||
await _storageService.SaveTaskDefinitionAsync(newTask);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -250,6 +269,51 @@ public partial class GearTaskListPageViewModel : ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑选中的任务定义
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task EditSelectedTaskDefinition()
|
||||
{
|
||||
if (SelectedTaskDefinition == null) return;
|
||||
|
||||
var editViewModel = App.GetService<TaskDefinitionEditWindowViewModel>();
|
||||
if (editViewModel == null) return;
|
||||
|
||||
editViewModel.Name = SelectedTaskDefinition.Name;
|
||||
editViewModel.Description = SelectedTaskDefinition.Description;
|
||||
|
||||
var editWindow = App.GetService<TaskDefinitionEditWindow>();
|
||||
if (editWindow == null) return;
|
||||
|
||||
editWindow.ViewModel.Name = editViewModel.Name;
|
||||
editWindow.ViewModel.Description = editViewModel.Description;
|
||||
editWindow.Owner = Application.Current.MainWindow;
|
||||
|
||||
if (editWindow.ShowDialog() == true)
|
||||
{
|
||||
SelectedTaskDefinition.Name = editWindow.ViewModel.Name;
|
||||
SelectedTaskDefinition.Description = editWindow.ViewModel.Description;
|
||||
SelectedTaskDefinition.ModifiedTime = DateTime.Now;
|
||||
|
||||
// 自动保存到文件
|
||||
await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition);
|
||||
|
||||
_logger.LogInformation("编辑了任务定义: {Name}", SelectedTaskDefinition.Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除选中的任务定义
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task DeleteSelectedTaskDefinition()
|
||||
{
|
||||
if (SelectedTaskDefinition == null) return;
|
||||
|
||||
await DeleteTaskDefinition(SelectedTaskDefinition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重命名任务定义
|
||||
/// </summary>
|
||||
@@ -375,32 +439,9 @@ public partial class GearTaskListPageViewModel : ViewModel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存所有任务定义到JSON文件
|
||||
/// 从JSON文件重新加载所有任务定义(内部使用)
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task SaveToJson()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var taskDefinition in TaskDefinitions)
|
||||
{
|
||||
await _storageService.SaveTaskDefinitionAsync(taskDefinition);
|
||||
}
|
||||
_logger.LogInformation("所有任务定义已保存到JSON文件");
|
||||
MessageBox.Show("保存成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "保存任务定义到JSON文件时发生错误");
|
||||
MessageBox.Show($"保存失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从JSON文件重新加载所有任务定义
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task LoadFromJson()
|
||||
private async Task LoadFromJsonInternal()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -414,12 +455,10 @@ public partial class GearTaskListPageViewModel : ViewModel
|
||||
}
|
||||
|
||||
_logger.LogInformation("从JSON文件重新加载了 {Count} 个任务定义", loadedTasks.Count);
|
||||
MessageBox.Show($"加载成功!共加载 {loadedTasks.Count} 个任务定义", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "从JSON文件加载任务定义时发生错误");
|
||||
MessageBox.Show($"加载失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace BetterGenshinImpact.ViewModel.Windows;
|
||||
|
||||
public partial class TaskDefinitionEditWindowViewModel : ObservableValidator
|
||||
{
|
||||
[ObservableProperty]
|
||||
[Required(ErrorMessage = "名称不能为空")]
|
||||
private string _name = "";
|
||||
|
||||
[ObservableProperty]
|
||||
private string _description = "";
|
||||
|
||||
public event EventHandler<bool>? RequestClose;
|
||||
|
||||
public TaskDefinitionEditWindowViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
public TaskDefinitionEditWindowViewModel(string name, string description = "")
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void Confirm()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RequestClose?.Invoke(this, true);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void Cancel()
|
||||
{
|
||||
RequestClose?.Invoke(this, false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user