fix: 修复启动隐藏与深色主题界面问题

修复托盘退出卡死、启动隐藏闪窗和隐藏实例再次启动无法唤醒的问题。

统一深色主题资源与控件模板,补齐卡片、内置图标、右键菜单和弹窗背景样式。

验证:dotnet build PersonalToolbox.sln;dotnet run --project tests\PersonalToolbox.Tests\PersonalToolbox.Tests.csproj。
This commit is contained in:
2026-05-27 17:43:22 +08:00
parent bbc183cef6
commit 3909764972
14 changed files with 720 additions and 152 deletions

View File

@@ -1,14 +1,14 @@
<Application x:Class="PersonalToolbox.App" <Application x:Class="PersonalToolbox.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:PersonalToolbox.Views" xmlns:views="clr-namespace:PersonalToolbox.Views">
StartupUri="MainWindow.xaml">
<Application.Resources> <Application.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<views:IconKeyToTextConverter x:Key="IconKeyToTextConverter" /> <views:IconKeyToTextConverter x:Key="IconKeyToTextConverter" />
<SolidColorBrush x:Key="AppBackgroundBrush" Color="#F7F8FA" /> <SolidColorBrush x:Key="AppBackgroundBrush" Color="#F7F8FA" />
<SolidColorBrush x:Key="PanelBackgroundBrush" Color="#FFFFFF" /> <SolidColorBrush x:Key="PanelBackgroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="CardBackgroundBrush" Color="#FBFCFE" /> <SolidColorBrush x:Key="CardBackgroundBrush" Color="#FBFCFE" />
<SolidColorBrush x:Key="SelectedCardBackgroundBrush" Color="#EFF5FF" />
<SolidColorBrush x:Key="BadgeBackgroundBrush" Color="#EDF2F7" /> <SolidColorBrush x:Key="BadgeBackgroundBrush" Color="#EDF2F7" />
<SolidColorBrush x:Key="IconBackgroundBrush" Color="#E8F0FF" /> <SolidColorBrush x:Key="IconBackgroundBrush" Color="#E8F0FF" />
<SolidColorBrush x:Key="BorderBrushSoft" Color="#D9DEE7" /> <SolidColorBrush x:Key="BorderBrushSoft" Color="#D9DEE7" />
@@ -16,23 +16,344 @@
<SolidColorBrush x:Key="PrimaryTextBrush" Color="#172033" /> <SolidColorBrush x:Key="PrimaryTextBrush" Color="#172033" />
<SolidColorBrush x:Key="SecondaryTextBrush" Color="#5C667A" /> <SolidColorBrush x:Key="SecondaryTextBrush" Color="#5C667A" />
<Style TargetType="Window">
<Setter Property="Background" Value="{DynamicResource AppBackgroundBrush}" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
</Style>
<Style TargetType="CheckBox">
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<Style TargetType="Button"> <Style TargetType="Button">
<Setter Property="MinHeight" Value="32" /> <Setter Property="MinHeight" Value="32" />
<Setter Property="Padding" Value="12,4" /> <Setter Property="Padding" Value="12,4" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="ButtonBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.55" />
<Setter Property="Foreground" Value="{DynamicResource SecondaryTextBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> </Style>
<Style TargetType="TextBox"> <Style TargetType="TextBox">
<Setter Property="Padding" Value="8,4" /> <Setter Property="Padding" Value="8,4" />
<Setter Property="MinHeight" Value="32" />
<Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="CaretBrush" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="SelectionBrush" Value="{DynamicResource PrimaryBrush}" />
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="TextBoxBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer x:Name="PART_ContentHost"
Margin="{TemplateBinding Padding}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter TargetName="TextBoxBorder" Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.55" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ComboBoxItem">
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="Padding" Value="8,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border x:Name="ItemBorder"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="ItemBorder" Property="Background" Value="{DynamicResource SelectedCardBackgroundBrush}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ItemBorder" Property="Background" Value="{DynamicResource SelectedCardBackgroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> </Style>
<Style TargetType="ComboBox"> <Style TargetType="ComboBox">
<Setter Property="Padding" Value="8,4" /> <Setter Property="Padding" Value="8,4" />
<Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="MinHeight" Value="32" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<Border x:Name="ComboBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<ContentPresenter x:Name="ContentSite"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" />
<Path Data="M 0 0 L 4 4 L 8 0 Z"
Fill="{DynamicResource SecondaryTextBrush}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Margin="0,0,10,0" />
<ToggleButton Background="Transparent"
BorderThickness="0"
Focusable="False"
Opacity="0"
IsChecked="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
ClickMode="Press" />
</Grid>
</Border>
<Popup x:Name="PART_Popup"
AllowsTransparency="True"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Fade">
<Border Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{DynamicResource BorderBrushSoft}"
BorderThickness="1"
MinWidth="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter TargetName="ComboBorder" Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ComboBorder" Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.55" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TabControl">
<Setter Property="Background" Value="{DynamicResource AppBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
</Style>
<Style TargetType="TabItem">
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="Padding" Value="10,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid>
<Border x:Name="TabBorder"
Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{DynamicResource BorderBrushSoft}"
BorderThickness="1,1,1,0"
Padding="{TemplateBinding Padding}">
<ContentPresenter ContentSource="Header"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="TabBorder" Property="Background" Value="{DynamicResource SelectedCardBackgroundBrush}" />
<Setter TargetName="TabBorder" Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="TabBorder" Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="DataGrid">
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="GridLinesVisibility" Value="Horizontal" />
<Setter Property="HorizontalGridLinesBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="VerticalGridLinesBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="RowBackground" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="AlternatingRowBackground" Value="{DynamicResource CardBackgroundBrush}" />
</Style>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background" Value="{DynamicResource CardBackgroundBrush}" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="Padding" Value="8,6" />
</Style>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
</Style>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="Padding" Value="6,4" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource SelectedCardBackgroundBrush}" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="ContextMenu">
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="4" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="MenuItem">
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="12,7" />
<Setter Property="MinWidth" Value="180" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Border x:Name="MenuItemBorder"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter ContentSource="Header"
RecognizesAccessKey="True"
VerticalAlignment="Center" />
<TextBlock Grid.Column="1"
Text="{TemplateBinding InputGestureText}"
Margin="24,0,0,0"
Foreground="{DynamicResource SecondaryTextBrush}"
VerticalAlignment="Center" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="MenuItemBorder" Property="Background" Value="{DynamicResource SelectedCardBackgroundBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.45" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ListBox">
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
</Style> </Style>
<Style TargetType="ListBoxItem"> <Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="ItemBorder"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ItemBorder" Property="Background" Value="{DynamicResource SelectedCardBackgroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> </Style>
</Application.Resources> </Application.Resources>
</Application> </Application>

View File

@@ -1,6 +1,10 @@
using System.Configuration; using System.Configuration;
using System.Data; using System.Data;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Windows; using System.Windows;
using System.Threading;
namespace PersonalToolbox; namespace PersonalToolbox;
@@ -9,5 +13,136 @@ namespace PersonalToolbox;
/// </summary> /// </summary>
public partial class App : System.Windows.Application public partial class App : System.Windows.Application
{ {
private const string ActivatePipeName = "PersonalToolbox.Activate";
private FileStream? _instanceLockFile;
private CancellationTokenSource? _activationPipeCancellation;
private MainWindow? _mainWindow;
protected override async void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ShutdownMode = ShutdownMode.OnExplicitShutdown;
if (!TryAcquireInstanceLock())
{
SignalExistingInstance();
Environment.Exit(0);
return;
}
var mainWindow = new MainWindow();
_mainWindow = mainWindow;
MainWindow = mainWindow;
StartActivationPipe();
await mainWindow.InitializeShellAsync();
if (!mainWindow.StartHiddenToTray)
{
mainWindow.ShowMainWindow();
}
else
{
mainWindow.RefreshTrayMenu();
}
await mainWindow.RunStartupTasksAsync();
}
protected override void OnExit(ExitEventArgs e)
{
_activationPipeCancellation?.Cancel();
_activationPipeCancellation?.Dispose();
_instanceLockFile?.Dispose();
base.OnExit(e);
}
private bool TryAcquireInstanceLock()
{
try
{
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var configDirectory = Path.Combine(appData, "PersonalToolbox");
Directory.CreateDirectory(configDirectory);
var lockPath = Path.Combine(configDirectory, "PersonalToolbox.lock");
_instanceLockFile = new FileStream(lockPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
_instanceLockFile.SetLength(0);
var processId = Encoding.UTF8.GetBytes(Environment.ProcessId.ToString());
_instanceLockFile.Write(processId, 0, processId.Length);
_instanceLockFile.Flush();
return true;
}
catch (IOException)
{
return false;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
private static void SignalExistingInstance()
{
for (var attempt = 0; attempt < 3; attempt++)
{
try
{
using var pipe = new NamedPipeClientStream(".", ActivatePipeName, PipeDirection.Out);
pipe.Connect(800);
using var writer = new StreamWriter(pipe, Encoding.UTF8)
{
AutoFlush = true
};
writer.WriteLine("show");
return;
}
catch (IOException)
{
}
catch (TimeoutException)
{
}
Thread.Sleep(150);
}
}
private void StartActivationPipe()
{
_activationPipeCancellation = new CancellationTokenSource();
_ = Task.Run(() => ListenForActivationAsync(_activationPipeCancellation.Token));
}
private async Task ListenForActivationAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
try
{
await using var pipe = new NamedPipeServerStream(
ActivatePipeName,
PipeDirection.In,
1,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);
await pipe.WaitForConnectionAsync(cancellationToken);
using var reader = new StreamReader(pipe, Encoding.UTF8);
_ = await reader.ReadLineAsync(cancellationToken);
await Dispatcher.BeginInvoke(() => _mainWindow?.ShowMainWindow());
}
catch (OperationCanceledException)
{
return;
}
catch (IOException)
{
}
}
}
} }

View File

@@ -1,4 +1,4 @@
<Window x:Class="PersonalToolbox.MainWindow" <Window x:Class="PersonalToolbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -10,8 +10,7 @@
Width="1120" Width="1120"
MinHeight="620" MinHeight="620"
MinWidth="960" MinWidth="960"
Background="{StaticResource AppBackgroundBrush}" Background="{DynamicResource AppBackgroundBrush}"
Loaded="Window_OnLoaded"
Closing="Window_OnClosing"> Closing="Window_OnClosing">
<Grid x:Name="RootGrid" Margin="16"> <Grid x:Name="RootGrid" Margin="16">
<Grid.RowDefinitions> <Grid.RowDefinitions>
@@ -20,8 +19,8 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Border Background="{StaticResource PanelBackgroundBrush}" <Border Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{StaticResource BorderBrushSoft}" BorderBrush="{DynamicResource BorderBrushSoft}"
BorderThickness="1" BorderThickness="1"
CornerRadius="8" CornerRadius="8"
Padding="12"> Padding="12">
@@ -78,8 +77,8 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Border Background="{StaticResource PanelBackgroundBrush}" <Border Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{StaticResource BorderBrushSoft}" BorderBrush="{DynamicResource BorderBrushSoft}"
BorderThickness="1" BorderThickness="1"
CornerRadius="8" CornerRadius="8"
Padding="12"> Padding="12">
@@ -93,7 +92,7 @@
<TextBlock Text="分类" <TextBlock Text="分类"
FontSize="16" FontSize="16"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{StaticResource PrimaryTextBrush}" Foreground="{DynamicResource PrimaryTextBrush}"
ToolTip="一级分类列表,工具只能属于一个分类。" /> ToolTip="一级分类列表,工具只能属于一个分类。" />
<ListBox Grid.Row="1" <ListBox Grid.Row="1"
@@ -112,14 +111,14 @@
<Border Width="32" <Border Width="32"
Height="26" Height="26"
CornerRadius="6" CornerRadius="6"
Background="{StaticResource IconBackgroundBrush}" Background="{DynamicResource IconBackgroundBrush}"
DockPanel.Dock="Left"> DockPanel.Dock="Left">
<TextBlock Text="{Binding IconKey, Converter={StaticResource IconKeyToTextConverter}}" <TextBlock Text="{Binding IconKey, Converter={StaticResource IconKeyToTextConverter}}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
FontSize="11" FontFamily="Segoe MDL2 Assets"
FontWeight="SemiBold" FontSize="16"
Foreground="{StaticResource PrimaryBrush}" /> Foreground="{DynamicResource PrimaryBrush}" />
</Border> </Border>
<TextBlock Text="{Binding Name}" <TextBlock Text="{Binding Name}"
Padding="8,7" Padding="8,7"
@@ -151,8 +150,8 @@
</Border> </Border>
<Border Grid.Column="2" <Border Grid.Column="2"
Background="{StaticResource PanelBackgroundBrush}" Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{StaticResource BorderBrushSoft}" BorderBrush="{DynamicResource BorderBrushSoft}"
BorderThickness="1" BorderThickness="1"
CornerRadius="8" CornerRadius="8"
Padding="12"> Padding="12">
@@ -179,12 +178,23 @@
<Border Width="{Binding CardWidth}" <Border Width="{Binding CardWidth}"
Height="{Binding CardHeight}" Height="{Binding CardHeight}"
Margin="6" Margin="6"
Padding="12" Padding="14"
CornerRadius="8" CornerRadius="8"
BorderThickness="1" BorderThickness="1"
BorderBrush="{StaticResource BorderBrushSoft}" Cursor="Hand"
Background="{StaticResource CardBackgroundBrush}"
ToolTip="{Binding DetailText}"> ToolTip="{Binding DetailText}">
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrushSoft}" />
<Setter Property="Background" Value="{DynamicResource CardBackgroundBrush}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}" />
<Setter Property="Background" Value="{DynamicResource SelectedCardBackgroundBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Border.ContextMenu> <Border.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="启动" <MenuItem Header="启动"
@@ -216,22 +226,26 @@
</Border.ContextMenu> </Border.ContextMenu>
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<DockPanel> <Grid>
<Border Width="42" <Grid.ColumnDefinitions>
Height="32" <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Width="60"
Height="60"
CornerRadius="6" CornerRadius="6"
Background="{StaticResource IconBackgroundBrush}" Background="{DynamicResource IconBackgroundBrush}"
DockPanel.Dock="Left"
ToolTip="工具图标,可来自自动缓存、内置图标库或本地图片。"> ToolTip="工具图标,可来自自动缓存、内置图标库或本地图片。">
<Grid> <Grid>
<Image Source="{Binding IconImagePath}" <Image Source="{Binding IconImagePath}"
Margin="4" Margin="6"
Stretch="Uniform"> Stretch="Uniform">
<Image.Style> <Image.Style>
<Style TargetType="Image"> <Style TargetType="Image">
@@ -247,8 +261,9 @@
<TextBlock Text="{Binding IconText}" <TextBlock Text="{Binding IconText}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
FontWeight="SemiBold" FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource PrimaryBrush}"> FontSize="30"
Foreground="{DynamicResource PrimaryBrush}">
<TextBlock.Style> <TextBlock.Style>
<Style TargetType="TextBlock"> <Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible" /> <Setter Property="Visibility" Value="Visible" />
@@ -262,26 +277,41 @@
</TextBlock> </TextBlock>
</Grid> </Grid>
</Border> </Border>
<TextBlock Text="{Binding TypeLabel}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Foreground="{StaticResource SecondaryTextBrush}"
ToolTip="工具类型标记。" />
</DockPanel>
<TextBlock Grid.Row="1" <StackPanel Grid.Column="1"
Text="{Binding Name}" Margin="12,2,8,0">
Margin="0,10,0,0" <TextBlock Text="{Binding Name}"
FontSize="15" FontSize="16"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{StaticResource PrimaryTextBrush}" Foreground="{DynamicResource PrimaryTextBrush}"
TextTrimming="CharacterEllipsis" TextTrimming="CharacterEllipsis"
ToolTip="{Binding Name}" /> ToolTip="{Binding Name}" />
<TextBlock Text="{Binding CategoryName}"
<TextBlock Grid.Row="2"
Text="{Binding Description}"
Margin="0,6,0,0" Margin="0,6,0,0"
Foreground="{StaticResource SecondaryTextBrush}" Foreground="{DynamicResource SecondaryTextBrush}"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding CategoryName}" />
</StackPanel>
<Border Grid.Column="2"
MinWidth="44"
Height="24"
Padding="8,2"
CornerRadius="4"
Background="{DynamicResource BadgeBackgroundBrush}"
ToolTip="工具类型标记。">
<TextBlock Text="{Binding TypeLabel}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="12"
Foreground="{DynamicResource SecondaryTextBrush}" />
</Border>
</Grid>
<TextBlock Grid.Row="1"
Text="{Binding Description}"
Margin="0,10,0,0"
Foreground="{DynamicResource SecondaryTextBrush}"
TextWrapping="Wrap" TextWrapping="Wrap"
TextTrimming="CharacterEllipsis" TextTrimming="CharacterEllipsis"
ToolTip="{Binding Description}"> ToolTip="{Binding Description}">
@@ -297,7 +327,7 @@
</TextBlock.Style> </TextBlock.Style>
</TextBlock> </TextBlock>
<ItemsControl Grid.Row="3" <ItemsControl Grid.Row="2"
ItemsSource="{Binding StatusBadges}" ItemsSource="{Binding StatusBadges}"
Margin="0,8,0,0" Margin="0,8,0,0"
ToolTip="状态标记:路径失效、快捷键、自动运行或管理员。"> ToolTip="状态标记:路径失效、快捷键、自动运行或管理员。">
@@ -308,13 +338,13 @@
</ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<Border Background="{StaticResource BadgeBackgroundBrush}" <Border Background="{DynamicResource BadgeBackgroundBrush}"
CornerRadius="4" CornerRadius="4"
Padding="5,2" Padding="5,2"
Margin="0,0,5,4"> Margin="0,0,5,4">
<TextBlock Text="{Binding}" <TextBlock Text="{Binding}"
FontSize="11" FontSize="11"
Foreground="{StaticResource SecondaryTextBrush}" /> Foreground="{DynamicResource SecondaryTextBrush}" />
</Border> </Border>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
@@ -331,8 +361,8 @@
Header="底部信息" Header="底部信息"
IsExpanded="{Binding IsLogPanelExpanded}" IsExpanded="{Binding IsLogPanelExpanded}"
ToolTip="显示启动、组合、自动运行、导入导出和错误信息。"> ToolTip="显示启动、组合、自动运行、导入导出和错误信息。">
<Border Background="{StaticResource PanelBackgroundBrush}" <Border Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{StaticResource BorderBrushSoft}" BorderBrush="{DynamicResource BorderBrushSoft}"
BorderThickness="1" BorderThickness="1"
CornerRadius="8" CornerRadius="8"
Padding="10" Padding="10"

View File

@@ -2,6 +2,7 @@ using System.ComponentModel;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using PersonalToolbox.Models; using PersonalToolbox.Models;
using PersonalToolbox.Services; using PersonalToolbox.Services;
@@ -17,6 +18,8 @@ public partial class MainWindow : Window
private TrayService? _trayService; private TrayService? _trayService;
private bool _initialized; private bool _initialized;
private bool _exitRequested; private bool _exitRequested;
private bool _isShuttingDown;
private bool _cleanupCompleted;
private System.Windows.Point _dragStartPoint; private System.Windows.Point _dragStartPoint;
public MainWindow() public MainWindow()
@@ -28,7 +31,9 @@ public partial class MainWindow : Window
DataContext = _viewModel; DataContext = _viewModel;
} }
private async void Window_OnLoaded(object sender, RoutedEventArgs e) public bool StartHiddenToTray => _viewModel.Data.Settings.StartHiddenToTray;
public async Task InitializeShellAsync()
{ {
if (_initialized) if (_initialized)
{ {
@@ -41,6 +46,7 @@ public partial class MainWindow : Window
Width = _viewModel.Data.Settings.MainWindowWidth; Width = _viewModel.Data.Settings.MainWindowWidth;
Height = _viewModel.Data.Settings.MainWindowHeight; Height = _viewModel.Data.Settings.MainWindowHeight;
new WindowInteropHelper(this).EnsureHandle();
_trayService = new TrayService( _trayService = new TrayService(
this, this,
@@ -50,18 +56,32 @@ public partial class MainWindow : Window
RequestExit); RequestExit);
RegisterHotkeys(); RegisterHotkeys();
if (_viewModel.Data.Settings.StartHiddenToTray)
{
Hide();
_trayService.RefreshMenuText();
} }
public async Task RunStartupTasksAsync()
{
await _viewModel.RunAutoRunAsync(); await _viewModel.RunAutoRunAsync();
} }
private void Window_OnClosing(object? sender, CancelEventArgs e) public void ShowMainWindow()
{ {
Show();
Activate();
RefreshTrayMenu();
}
public void RefreshTrayMenu()
{
_trayService?.RefreshMenuText();
}
private async void Window_OnClosing(object? sender, CancelEventArgs e)
{
if (_cleanupCompleted)
{
return;
}
if (!_exitRequested && _viewModel.Data.Settings.HideOnClose) if (!_exitRequested && _viewModel.Data.Settings.HideOnClose)
{ {
e.Cancel = true; e.Cancel = true;
@@ -70,11 +90,8 @@ public partial class MainWindow : Window
return; return;
} }
_viewModel.Data.Settings.MainWindowWidth = Width; e.Cancel = true;
_viewModel.Data.Settings.MainWindowHeight = Height; await ShutdownAsync();
_viewModel.SaveAsync().GetAwaiter().GetResult();
_hotkeyService.Dispose();
_trayService?.Dispose();
} }
private void SearchTextBox_OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e) private void SearchTextBox_OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
@@ -298,16 +315,11 @@ public partial class MainWindow : Window
RootGrid.LayoutTransform = new ScaleTransform(scale, scale); RootGrid.LayoutTransform = new ScaleTransform(scale, scale);
} }
private void RequestExit() private async void RequestExit()
{ {
if (_viewModel.Data.Settings.ConfirmExit) if (_viewModel.Data.Settings.ConfirmExit)
{ {
var confirmed = MessageBox.Show( var confirmed = ShowExitConfirmation() == MessageBoxResult.Yes;
this,
"确定退出个人工具箱吗?退出后托盘和全局快捷键都会停止。",
"退出",
MessageBoxButton.YesNo,
MessageBoxImage.Question) == MessageBoxResult.Yes;
if (!confirmed) if (!confirmed)
{ {
@@ -315,10 +327,48 @@ public partial class MainWindow : Window
} }
} }
await ShutdownAsync();
}
private MessageBoxResult ShowExitConfirmation()
{
const string message = "确定退出个人工具箱吗?退出后托盘和全局快捷键都会停止。";
if (IsVisible)
{
return MessageBox.Show(this, message, "退出", MessageBoxButton.YesNo, MessageBoxImage.Question);
}
return MessageBox.Show(message, "退出", MessageBoxButton.YesNo, MessageBoxImage.Question);
}
private async Task ShutdownAsync()
{
if (_isShuttingDown)
{
return;
}
_isShuttingDown = true;
_exitRequested = true; _exitRequested = true;
Close(); _viewModel.Data.Settings.MainWindowWidth = Width;
_viewModel.Data.Settings.MainWindowHeight = Height;
try
{
await _viewModel.SaveAsync();
}
catch (Exception ex)
{
_viewModel.AddLog(LogLevel.Error, $"退出前保存配置失败:{ex.Message}");
}
finally
{
_hotkeyService.Dispose();
_trayService?.Dispose();
_cleanupCompleted = true;
System.Windows.Application.Current.Shutdown(); System.Windows.Application.Current.Shutdown();
} }
}
private static T? FindParent<T>(DependencyObject child) private static T? FindParent<T>(DependencyObject child)
where T : DependencyObject where T : DependencyObject

View File

@@ -14,6 +14,7 @@ public static class AppearanceService
SetBrush(resources, "AppBackgroundBrush", theme == "Dark" ? "#151922" : "#F7F8FA"); SetBrush(resources, "AppBackgroundBrush", theme == "Dark" ? "#151922" : "#F7F8FA");
SetBrush(resources, "PanelBackgroundBrush", theme == "Dark" ? "#1F2530" : "#FFFFFF"); SetBrush(resources, "PanelBackgroundBrush", theme == "Dark" ? "#1F2530" : "#FFFFFF");
SetBrush(resources, "CardBackgroundBrush", theme == "Dark" ? "#252C38" : "#FBFCFE"); SetBrush(resources, "CardBackgroundBrush", theme == "Dark" ? "#252C38" : "#FBFCFE");
SetBrush(resources, "SelectedCardBackgroundBrush", theme == "Dark" ? "#243B5E" : "#EFF5FF");
SetBrush(resources, "BadgeBackgroundBrush", theme == "Dark" ? "#303847" : "#EDF2F7"); SetBrush(resources, "BadgeBackgroundBrush", theme == "Dark" ? "#303847" : "#EDF2F7");
SetBrush(resources, "IconBackgroundBrush", theme == "Dark" ? "#263D63" : "#E8F0FF"); SetBrush(resources, "IconBackgroundBrush", theme == "Dark" ? "#263D63" : "#E8F0FF");
SetBrush(resources, "BorderBrushSoft", theme == "Dark" ? "#3B4658" : "#D9DEE7"); SetBrush(resources, "BorderBrushSoft", theme == "Dark" ? "#3B4658" : "#D9DEE7");
@@ -58,6 +59,13 @@ public static class AppearanceService
private static void SetBrush(ResourceDictionary resources, string key, string color) private static void SetBrush(ResourceDictionary resources, string key, string color)
{ {
resources[key] = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(color)); var parsed = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(color);
if (resources[key] is SolidColorBrush existingBrush && !existingBrush.IsFrozen)
{
existingBrush.Color = parsed;
return;
}
resources[key] = new SolidColorBrush(parsed);
} }
} }

View File

@@ -84,11 +84,11 @@ public sealed class IconService
return type switch return type switch
{ {
ToolType.System => "SYS", ToolType.System => "\uE770",
ToolType.Local => "APP", ToolType.Local => "\uE8A5",
ToolType.Url => "URL", ToolType.Url => "\uE71B",
ToolType.Combination => "COM", ToolType.Combination => "\uE8FD",
_ => "BOX" _ => "\uE90F"
}; };
} }
@@ -191,41 +191,41 @@ public static class IconCatalog
{ {
private static readonly IReadOnlyList<IconDefinition> Definitions = private static readonly IReadOnlyList<IconDefinition> Definitions =
[ [
new("toolbox", "工具箱", "通用", "BOX"), new("toolbox", "工具箱", "通用", "\uE90F"),
new("category", "分类", "通用", "TAG"), new("category", "分类", "通用", "\uE71D"),
new("system", "系统", "系统", "SYS"), new("system", "系统", "系统", "\uE770"),
new("settings", "设置", "系统", "SET"), new("settings", "设置", "系统", "\uE713"),
new("notepad", "记事本", "系统", "TXT"), new("notepad", "记事本", "系统", "\uE8A5"),
new("calculator", "计算器", "系统", "123"), new("calculator", "计算器", "系统", "\uE8EF"),
new("taskmgr", "任务管理器", "系统", "CPU"), new("taskmgr", "任务管理器", "系统", "\uE9D9"),
new("control", "控制面板", "系统", "CTL"), new("control", "控制面板", "系统", "\uE713"),
new("device", "设备管理器", "系统", "DEV"), new("device", "设备管理器", "系统", "\uE772"),
new("disk", "磁盘", "系统", "DSK"), new("disk", "磁盘", "系统", "\uEDA2"),
new("service", "服务", "系统", "SVC"), new("service", "服务", "系统", "\uE9F5"),
new("registry", "注册表", "系统", "REG"), new("registry", "注册表", "系统", "\uE8A5"),
new("network", "网络", "系统", "NET"), new("network", "网络", "系统", "\uE774"),
new("apps", "应用列表", "系统", "APP"), new("apps", "应用列表", "系统", "\uE71D"),
new("local", "本地工具", "文件", "APP"), new("local", "本地工具", "文件", "\uE8A5"),
new("file", "文件", "文件", "FIL"), new("file", "文件", "文件", "\uE8A5"),
new("folder", "文件夹", "文件", "DIR"), new("folder", "文件夹", "文件", "\uE8B7"),
new("document", "文档", "文件", "DOC"), new("document", "文档", "文件", "\uE8A5"),
new("image", "图片", "文件", "IMG"), new("image", "图片", "文件", "\uE91B"),
new("video", "视频", "文件", "VID"), new("video", "视频", "文件", "\uE714"),
new("audio", "音频", "文件", "AUD"), new("audio", "音频", "文件", "\uE8D6"),
new("archive", "压缩包", "文件", "ZIP"), new("archive", "压缩包", "文件", "\uE8B7"),
new("code", "代码", "文件", "COD"), new("code", "代码", "文件", "\uE943"),
new("script", "脚本", "操作", "CMD"), new("script", "脚本", "操作", "\uE756"),
new("link", "网址", "操作", "URL"), new("link", "网址", "操作", "\uE71B"),
new("combination", "组合", "工作区", "COM"), new("combination", "组合", "工作区", "\uE8FD"),
new("work", "工作", "工作区", "WRK"), new("work", "工作", "工作区", "\uE821"),
new("study", "学习", "工作区", "STD"), new("study", "学习", "工作区", "\uE82D"),
new("edit", "剪辑", "工作区", "CUT"), new("edit", "剪辑", "工作区", "\uE70F"),
new("design", "设计", "工作区", "DSN"), new("design", "设计", "工作区", "\uEC87"),
new("dev", "开发", "工作区", "DEV"), new("dev", "开发", "工作区", "\uE943"),
new("ai", "AI", "工作区", "AI"), new("ai", "AI", "工作区", "\uE950"),
new("star", "星标", "通用", "STR"), new("star", "星标", "通用", "\uE734"),
new("flash", "闪电", "通用", "PWR"), new("flash", "闪电", "通用", "\uE945"),
new("grid", "网格", "通用", "GRD") new("grid", "网格", "通用", "\uE80A")
]; ];
public static IReadOnlyList<IconDefinition> All => Definitions; public static IReadOnlyList<IconDefinition> All => Definitions;

View File

@@ -33,16 +33,16 @@ public sealed class ToolCardViewModel : ObservableObject
public bool ShowDescription => _settings.ShowToolDescriptions; public bool ShowDescription => _settings.ShowToolDescriptions;
public double CardWidth => _settings.CardSize switch public double CardWidth => _settings.CardSize switch
{ {
"Small" => 178, "Small" => 220,
"Large" => 248, "Large" => 320,
_ => 210 _ => 260
}; };
public double CardHeight => _settings.CardSize switch public double CardHeight => _settings.CardSize switch
{ {
"Small" => 126, "Small" => 132,
"Large" => 172, "Large" => 178,
_ => 146 _ => 154
}; };
public string TypeLabel => Tool.Type switch public string TypeLabel => Tool.Type switch

View File

@@ -6,8 +6,11 @@
Height="420" Height="420"
MinWidth="320" MinWidth="320"
MinHeight="360" MinHeight="360"
Background="{DynamicResource AppBackgroundBrush}"
Foreground="{DynamicResource PrimaryTextBrush}"
WindowStartupLocation="CenterOwner"> WindowStartupLocation="CenterOwner">
<Grid Margin="16"> <Grid Margin="16"
Background="{DynamicResource AppBackgroundBrush}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />

View File

@@ -1,4 +1,4 @@
<Window x:Class="PersonalToolbox.Views.CombinationEditorWindow" <Window x:Class="PersonalToolbox.Views.CombinationEditorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="编辑组合" Title="编辑组合"
@@ -6,8 +6,11 @@
Height="640" Height="640"
MinWidth="680" MinWidth="680"
MinHeight="560" MinHeight="560"
Background="{DynamicResource AppBackgroundBrush}"
Foreground="{DynamicResource PrimaryTextBrush}"
WindowStartupLocation="CenterOwner"> WindowStartupLocation="CenterOwner">
<Grid Margin="18"> <Grid Margin="18"
Background="{DynamicResource AppBackgroundBrush}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
@@ -107,17 +110,18 @@
<Border Width="42" <Border Width="42"
Height="30" Height="30"
CornerRadius="6" CornerRadius="6"
Background="{StaticResource IconBackgroundBrush}"> Background="{DynamicResource IconBackgroundBrush}">
<TextBlock x:Name="IconPreviewTextBlock" <TextBlock x:Name="IconPreviewTextBlock"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
FontWeight="SemiBold" FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource PrimaryBrush}" /> FontSize="18"
Foreground="{DynamicResource PrimaryBrush}" />
</Border> </Border>
<TextBlock x:Name="IconNameTextBlock" <TextBlock x:Name="IconNameTextBlock"
Margin="10,0,0,0" Margin="10,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{StaticResource SecondaryTextBrush}" /> Foreground="{DynamicResource SecondaryTextBrush}" />
<Button Content="选择图标" <Button Content="选择图标"
Width="88" Width="88"
Margin="12,0,0,0" Margin="12,0,0,0"

View File

@@ -1,4 +1,4 @@
<Window x:Class="PersonalToolbox.Views.HotkeyCaptureWindow" <Window x:Class="PersonalToolbox.Views.HotkeyCaptureWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="录入快捷键" Title="录入快捷键"
@@ -6,34 +6,37 @@
Height="220" Height="220"
MinWidth="380" MinWidth="380"
MinHeight="200" MinHeight="200"
Background="{DynamicResource AppBackgroundBrush}"
Foreground="{DynamicResource PrimaryTextBrush}"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
PreviewKeyDown="Window_OnPreviewKeyDown"> PreviewKeyDown="Window_OnPreviewKeyDown">
<Grid Margin="18"> <Grid Margin="18"
Background="{DynamicResource AppBackgroundBrush}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Border BorderBrush="{StaticResource BorderBrushSoft}" <Border BorderBrush="{DynamicResource BorderBrushSoft}"
BorderThickness="1" BorderThickness="1"
CornerRadius="8" CornerRadius="8"
Padding="18" Padding="18"
Background="{StaticResource PanelBackgroundBrush}"> Background="{DynamicResource PanelBackgroundBrush}">
<StackPanel VerticalAlignment="Center"> <StackPanel VerticalAlignment="Center">
<TextBlock Text="请按下要使用的快捷键" <TextBlock Text="请按下要使用的快捷键"
FontSize="16" FontSize="16"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{StaticResource PrimaryTextBrush}" /> Foreground="{DynamicResource PrimaryTextBrush}" />
<TextBlock Text="需要至少包含 Ctrl、Alt、Shift 或 Win 中的一个修饰键。" <TextBlock Text="需要至少包含 Ctrl、Alt、Shift 或 Win 中的一个修饰键。"
Margin="0,8,0,0" Margin="0,8,0,0"
TextWrapping="Wrap" TextWrapping="Wrap"
Foreground="{StaticResource SecondaryTextBrush}" /> Foreground="{DynamicResource SecondaryTextBrush}" />
<TextBlock x:Name="CapturedTextBlock" <TextBlock x:Name="CapturedTextBlock"
Text="等待输入..." Text="等待输入..."
Margin="0,18,0,0" Margin="0,18,0,0"
FontSize="22" FontSize="22"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{StaticResource PrimaryBrush}" Foreground="{DynamicResource PrimaryBrush}"
ToolTip="捕获到有效组合后会自动关闭窗口。" /> ToolTip="捕获到有效组合后会自动关闭窗口。" />
</StackPanel> </StackPanel>
</Border> </Border>

View File

@@ -1,4 +1,4 @@
<Window x:Class="PersonalToolbox.Views.IconPickerWindow" <Window x:Class="PersonalToolbox.Views.IconPickerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="选择图标" Title="选择图标"
@@ -6,8 +6,11 @@
Height="520" Height="520"
MinWidth="460" MinWidth="460"
MinHeight="440" MinHeight="440"
Background="{DynamicResource AppBackgroundBrush}"
Foreground="{DynamicResource PrimaryTextBrush}"
WindowStartupLocation="CenterOwner"> WindowStartupLocation="CenterOwner">
<Grid Margin="16"> <Grid Margin="16"
Background="{DynamicResource AppBackgroundBrush}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
@@ -42,21 +45,22 @@
<Border Width="42" <Border Width="42"
Height="30" Height="30"
CornerRadius="6" CornerRadius="6"
Background="{StaticResource IconBackgroundBrush}"> Background="{DynamicResource IconBackgroundBrush}">
<TextBlock Text="{Binding Text}" <TextBlock Text="{Binding Text}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
FontWeight="SemiBold" FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource PrimaryBrush}" /> FontSize="18"
Foreground="{DynamicResource PrimaryBrush}" />
</Border> </Border>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Text="{Binding Name}" Text="{Binding Name}"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{StaticResource PrimaryTextBrush}" /> Foreground="{DynamicResource PrimaryTextBrush}" />
<TextBlock Grid.Column="2" <TextBlock Grid.Column="2"
Text="{Binding Group}" Text="{Binding Group}"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{StaticResource SecondaryTextBrush}" /> Foreground="{DynamicResource SecondaryTextBrush}" />
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>

View File

@@ -5,8 +5,11 @@
Width="380" Width="380"
Height="180" Height="180"
ResizeMode="NoResize" ResizeMode="NoResize"
Background="{DynamicResource AppBackgroundBrush}"
Foreground="{DynamicResource PrimaryTextBrush}"
WindowStartupLocation="CenterOwner"> WindowStartupLocation="CenterOwner">
<Grid Margin="18"> <Grid Margin="18"
Background="{DynamicResource AppBackgroundBrush}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />

View File

@@ -1,4 +1,4 @@
<Window x:Class="PersonalToolbox.Views.SettingsWindow" <Window x:Class="PersonalToolbox.Views.SettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="设置" Title="设置"
@@ -6,8 +6,11 @@
Height="620" Height="620"
MinWidth="740" MinWidth="740"
MinHeight="540" MinHeight="540"
Background="{DynamicResource AppBackgroundBrush}"
Foreground="{DynamicResource PrimaryTextBrush}"
WindowStartupLocation="CenterOwner"> WindowStartupLocation="CenterOwner">
<Grid Margin="18"> <Grid Margin="18"
Background="{DynamicResource AppBackgroundBrush}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
@@ -102,7 +105,7 @@
Width="54" Width="54"
Margin="12,0,0,0" Margin="12,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{StaticResource SecondaryTextBrush}" /> Foreground="{DynamicResource SecondaryTextBrush}" />
</StackPanel> </StackPanel>
<CheckBox x:Name="ShowDescriptionCheckBox" <CheckBox x:Name="ShowDescriptionCheckBox"

View File

@@ -1,12 +1,15 @@
<Window x:Class="PersonalToolbox.Views.ToolEditorWindow" <Window x:Class="PersonalToolbox.Views.ToolEditorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="编辑工具" Title="编辑工具"
Width="560" Width="560"
Height="620" Height="620"
MinWidth="520" MinWidth="520"
Background="{DynamicResource AppBackgroundBrush}"
Foreground="{DynamicResource PrimaryTextBrush}"
WindowStartupLocation="CenterOwner"> WindowStartupLocation="CenterOwner">
<Grid Margin="18"> <Grid Margin="18"
Background="{DynamicResource AppBackgroundBrush}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
@@ -158,17 +161,18 @@
<Border Width="42" <Border Width="42"
Height="30" Height="30"
CornerRadius="6" CornerRadius="6"
Background="{StaticResource IconBackgroundBrush}"> Background="{DynamicResource IconBackgroundBrush}">
<TextBlock x:Name="IconPreviewTextBlock" <TextBlock x:Name="IconPreviewTextBlock"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
FontWeight="SemiBold" FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource PrimaryBrush}" /> FontSize="18"
Foreground="{DynamicResource PrimaryBrush}" />
</Border> </Border>
<TextBlock x:Name="IconNameTextBlock" <TextBlock x:Name="IconNameTextBlock"
Margin="10,0,0,0" Margin="10,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{StaticResource SecondaryTextBrush}" /> Foreground="{DynamicResource SecondaryTextBrush}" />
<Button Content="选择图标" <Button Content="选择图标"
Width="88" Width="88"
Margin="12,0,0,0" Margin="12,0,0,0"