调度器UI初版

This commit is contained in:
辉鸭蛋
2025-06-13 23:27:28 +08:00
parent 7fbd1ee04e
commit 259d4193a8
5 changed files with 527 additions and 0 deletions

View File

@@ -107,6 +107,8 @@ public partial class App : Application
services.AddSingleton<PathingConfigViewModel>();
// services.AddView<PathingConfigView, PathingConfigViewModel>();
services.AddView<KeyBindingsSettingsPage, KeyBindingsSettingsPageViewModel>();
services.AddView<SchedulerPage, SchedulerViewModel>();
// 一条龙 ViewModels
// services.AddSingleton<CraftViewModel>();

View File

@@ -122,6 +122,14 @@
<ui:SymbolIcon Symbol="Record24" />
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="调度器2"
NavigationCacheMode="Enabled"
TargetPageType="{x:Type pages:SchedulerPage}">
<ui:NavigationViewItem.Icon>
<ui:SymbolIcon Symbol="Script16" />
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
</ui:NavigationViewItem.MenuItems>
</ui:NavigationViewItem>

View File

@@ -0,0 +1,400 @@
<UserControl x:Class="BetterGenshinImpact.View.Pages.SchedulerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dd="urn:gong-wpf-dragdrop"
xmlns:local="clr-namespace:BetterGenshinImpact.View.Pages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pages="clr-namespace:BetterGenshinImpact.ViewModel.Pages"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
d:DataContext="{d:DesignInstance Type=pages:SchedulerViewModel}"
d:DesignHeight="850"
d:DesignWidth="800"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
FontFamily="{StaticResource TextThemeFontFamily}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/View/Controls/Style/ListViewEx.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="ConsistentTabControlStyle" TargetType="TabControl"
BasedOn="{StaticResource {x:Type TabControl}}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid x:Name="templateRoot"
Background="{TemplateBinding Background}"
ClipToBounds="True"
SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0" Width="Auto" />
<ColumnDefinition x:Name="ColumnDefinition1" Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto" />
<RowDefinition x:Name="RowDefinition1" Height="*" />
</Grid.RowDefinitions>
<TabPanel x:Name="headerPanel"
Grid.Column="0"
Grid.Row="0"
Background="Transparent"
IsItemsHost="True"
Panel.ZIndex="1" />
<Border x:Name="contentPanel"
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="1"
Background="{ui:ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderThickness="0">
<ContentPresenter x:Name="PART_SelectedContentHost"
ContentTemplate="{TemplateBinding SelectedContentTemplate}"
Content="{TemplateBinding SelectedContent}"
ContentStringFormat="{TemplateBinding SelectedContentStringFormat}"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ConsistentTabItemStyle" TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Width" Value="36" />
<Setter Property="Height" Value="26" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="templateRoot"
Background="Transparent"
SnapsToDevicePixels="True">
<Border x:Name="mainBorder"
Background="{ui:ThemeResource CardBackgroundFillColorSecondaryBrush}"
BorderThickness="0"
CornerRadius="8,8,0,0"
Margin="0,0,1,0">
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Content="{TemplateBinding Header}"
ContentStringFormat="{TemplateBinding HeaderStringFormat}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{ui:ThemeResource TextFillColorPrimaryBrush}" />
<Setter TargetName="mainBorder" Property="Background"
Value="{ui:ThemeResource CardBackgroundFillColorDefaultBrush}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="{ui:ThemeResource TextFillColorPrimaryBrush}" />
<Setter TargetName="mainBorder" Property="Background"
Value="{ui:ThemeResource CardBackgroundFillColorDefaultBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid Margin="8,0,8,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="220" />
<ColumnDefinition Width="0" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- 左侧触发模式选择区域 -->
<Border Grid.Column="0"
Margin="0,8,0,8"
CornerRadius="8">
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TabControl Grid.Row="1" Style="{StaticResource ConsistentTabControlStyle}">
<!-- 顺序触发选项卡 -->
<TabItem Style="{StaticResource ConsistentTabItemStyle}">
<TabItem.Header>
<ui:SymbolIcon Symbol="Play24" />
</TabItem.Header>
<Grid>
<StackPanel Margin="8">
<ui:TextBlock Margin="0,0,0,8"
Text="按照设定的顺序依次执行任务"
TextWrapping="Wrap" />
<ui:Card Margin="0,8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<ui:ToggleSwitch Content="启用顺序触发"
IsChecked="{Binding IsSequentialEnabled, Mode=TwoWay}" />
<ui:NumberBox Margin="0,8,0,0"
Value="{Binding SequentialInterval, Mode=TwoWay}"
Minimum="0" />
</StackPanel>
<ui:Button Grid.Row="1"
Margin="0,8,0,0"
HorizontalAlignment="Right"
Content="立即执行"
Command="{Binding StartSequentialCommand}"
Icon="{ui:SymbolIcon Play24}" />
</Grid>
</ui:Card>
</StackPanel>
</Grid>
</TabItem>
<!-- 定时触发选项卡 -->
<TabItem Style="{StaticResource ConsistentTabItemStyle}">
<TabItem.Header>
<ui:SymbolIcon Symbol="Clock24" />
</TabItem.Header>
<Grid>
<StackPanel Margin="8">
<ui:TextBlock Margin="0,0,0,8"
Text="在指定时间点触发任务执行"
TextWrapping="Wrap" />
<ui:Card Margin="0,8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<ui:ToggleSwitch Content="启用定时触发"
IsChecked="{Binding IsScheduledEnabled, Mode=TwoWay}" />
<ui:TimePicker Margin="0,8,0,0"
Header="触发时间"
SelectedTime="{Binding ScheduledTime, Mode=TwoWay}" />
<CheckBox Margin="0,8,0,0"
Content="每天重复"
IsChecked="{Binding IsRepeatDaily, Mode=TwoWay}" />
</StackPanel>
<ui:TextBlock Grid.Row="1"
Margin="0,8,0,0"
Text="{Binding NextScheduledRunText}"
TextWrapping="Wrap" />
<ui:Button Grid.Row="2"
Margin="0,8,0,0"
HorizontalAlignment="Right"
Content="立即执行"
Command="{Binding StartScheduledCommand}"
Icon="{ui:SymbolIcon Play24}" />
</Grid>
</ui:Card>
</StackPanel>
</Grid>
</TabItem>
<!-- 热键触发选项卡 -->
<TabItem Style="{StaticResource ConsistentTabItemStyle}">
<TabItem.Header>
<ui:SymbolIcon Symbol="Keyboard24" />
</TabItem.Header>
<Grid>
<StackPanel Margin="8">
<ui:TextBlock Margin="0,0,0,8"
Text="通过热键组合触发任务执行"
TextWrapping="Wrap" />
<ui:Card Margin="0,8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<ui:ToggleSwitch Content="启用热键触发"
IsChecked="{Binding IsHotkeyEnabled, Mode=TwoWay}" />
<ui:TextBox Margin="0,8,0,0"
Text="{Binding HotkeyString, Mode=TwoWay}"
PlaceholderText="点击后按下组合键..." />
</StackPanel>
<ui:Button Grid.Row="1"
Margin="0,8,0,0"
HorizontalAlignment="Right"
Content="立即执行"
Command="{Binding StartHotkeyCommand}"
Icon="{ui:SymbolIcon Play24}" />
</Grid>
</ui:Card>
</StackPanel>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Border>
<!-- 右侧任务管理区域 -->
<Border Grid.Column="2"
Margin="6"
Background="{ui:ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ui:ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8">
<Grid Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- 标题 -->
<ui:TextBlock Grid.Row="0"
Margin="0,0,0,8"
FontTypography="BodyStrong"
Text="任务调度器" />
<!-- 描述 -->
<ui:TextBlock Grid.Row="1"
Margin="0,0,0,12"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
TextWrapping="Wrap"
Text="通过不同的触发方式执行预设的任务序列,支持顺序执行、定时执行和热键触发。" />
<!-- 操作按钮 -->
<StackPanel Grid.Row="2"
Orientation="Horizontal"
Margin="0,0,0,12">
<ui:Button Command="{Binding AddTaskCommand}"
Content="添加任务"
Icon="{ui:SymbolIcon Add24}" />
<Separator Width="10" Opacity="0" />
<ui:DropDownButton Content="导入导出"
Icon="{ui:SymbolIcon ArrowAutofitDown20}">
<ui:DropDownButton.Flyout>
<ContextMenu>
<MenuItem Header="导入任务配置" Command="{Binding ImportTasksCommand}" />
<MenuItem Header="导出任务配置" Command="{Binding ExportTasksCommand}" />
</ContextMenu>
</ui:DropDownButton.Flyout>
</ui:DropDownButton>
<Separator Width="10" Opacity="0" />
<ui:Button Command="{Binding SettingsCommand}"
Content="全局设置"
Icon="{ui:SymbolIcon Settings24}" />
</StackPanel>
<!-- 列表标题 -->
<Grid Grid.Row="3" Margin="0,0,0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid x:Name="Col1" Grid.Column="0" />
<Grid x:Name="Col2" Grid.Column="1" />
<Grid x:Name="Col3" Grid.Column="2" />
<Grid x:Name="Col4" Grid.Column="3" />
</Grid>
<!-- 任务列表 -->
<ui:ListView Grid.Row="4"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True"
ItemsSource="{Binding Tasks, Mode=TwoWay}"
SelectionMode="Single">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource GridViewColumnHeaderDarkStyle}">
<GridViewColumn Width="{Binding ElementName=Col1, Path=ActualWidth}"
DisplayMemberBinding="{Binding Index}"
Header="#" />
<GridViewColumn Width="{Binding ElementName=Col2, Path=ActualWidth}"
Header="任务名称">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" FontSize="14" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="{Binding ElementName=Col3, Path=ActualWidth}"
DisplayMemberBinding="{Binding TypeDescription}"
Header="任务类型" />
<GridViewColumn Width="{Binding ElementName=Col4, Path=ActualWidth}"
Header="启用状态">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ui:ToggleSwitch IsChecked="{Binding IsEnabled, Mode=TwoWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding AddTaskCommand}"
Header="添加任务" />
<MenuItem Command="{Binding EditTaskCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"
Header="编辑任务" />
<MenuItem Command="{Binding DuplicateTaskCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"
Header="复制任务" />
<MenuItem Command="{Binding DeleteTaskCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"
Header="删除任务" />
</ContextMenu>
</ListView.ContextMenu>
<ListView.Style>
<Style TargetType="{x:Type ListView}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
</Style>
</ListView.Style>
</ui:ListView>
</Grid>
</Border>
</Grid>
</UserControl>

View File

@@ -0,0 +1,11 @@
using System.Windows.Controls;
namespace BetterGenshinImpact.View.Pages;
public partial class SchedulerPage
{
public SchedulerPage()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace BetterGenshinImpact.ViewModel.Pages;
public partial class SchedulerViewModel : ViewModel
{
// 顺序触发相关属性
[ObservableProperty] private bool _isSequentialEnabled;
[ObservableProperty] private double _sequentialInterval = 5;
// 定时触发相关属性
[ObservableProperty] private bool _isScheduledEnabled;
[ObservableProperty] private DateTime _scheduledTime = DateTime.Now;
[ObservableProperty] private bool _isRepeatDaily;
[ObservableProperty] private string _nextScheduledRunText = "下次执行: 未设置";
// 热键触发相关属性
[ObservableProperty] private bool _isHotkeyEnabled;
[ObservableProperty] private string _hotkeyString = "";
// 任务列表
[ObservableProperty] private ObservableCollection<SchedulerTask> _tasks = new();
// 命令
[RelayCommand]
private void StartSequential()
{
// 实现顺序触发逻辑
}
[RelayCommand]
private void StartScheduled()
{
// 实现定时触发逻辑
}
[RelayCommand]
private void StartHotkey()
{
// 实现热键触发逻辑
}
[RelayCommand]
private void AddTask()
{
// 实现添加任务逻辑
}
[RelayCommand]
private void EditTask(SchedulerTask task)
{
// 实现编辑任务逻辑
}
[RelayCommand]
private void DuplicateTask(SchedulerTask task)
{
// 实现复制任务逻辑
}
[RelayCommand]
private void DeleteTask(SchedulerTask task)
{
// 实现删除任务逻辑
}
[RelayCommand]
private void ImportTasks()
{
// 实现导入任务逻辑
}
[RelayCommand]
private void ExportTasks()
{
// 实现导出任务逻辑
}
[RelayCommand]
private void Settings()
{
// 实现全局设置逻辑
}
}
// 任务模型
public partial class SchedulerTask : ObservableObject
{
public int Index { get; set; }
[ObservableProperty] private string _name;
[ObservableProperty] private string _typeDescription;
[ObservableProperty] private bool _isEnabled = true;
// 其他任务属性
}