Files
personal-toolbox/PersonalToolBox/Views/MainWindow.xaml
home-PC b715904439 新增工具/组合随软件启动自动运行功能
- ToolItem 模型新增 AutoRunOnStart 属性,持久化到配置文件
- App.OnStartup 启动后自动执行标记为自启动的工具/组合(间隔500ms)
- 工具编辑窗口和组合编辑窗口新增「随软件启动自动运行」CheckBox
- 主界面工具卡片左上角 Rocket 角标标识已启用自启的项目
2026-05-10 02:51:29 +08:00

437 lines
24 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Window x:Class="PersonalToolBox.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PersonalToolBox.Views"
xmlns:vm="clr-namespace:PersonalToolBox.ViewModels"
xmlns:models="clr-namespace:PersonalToolBox.Models"
xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp"
mc:Ignorable="d"
Title="个人工具箱" Height="650" Width="960"
WindowStartupLocation="CenterScreen"
Background="{DynamicResource Theme.Background}">
<Window.Resources>
<!-- 值转换器(必须定义在 DataTemplate 之前,确保 StaticResource 能解析) -->
<local:BoolToOpacityConverter x:Key="BoolToOpacityConverter"/>
<local:FirstCharConverter x:Key="FirstCharConverter"/>
<local:StringToIconCharConverter x:Key="StringToIconCharConverter"/>
<!-- 工具卡片模板 -->
<DataTemplate x:Key="ToolCardTemplate" DataType="{x:Type models:ToolItem}">
<Border Width="140" Height="100"
Margin="6"
Background="{DynamicResource Theme.CardBackground}"
BorderBrush="{DynamicResource Theme.CardBorder}"
BorderThickness="1"
CornerRadius="8"
Opacity="{Binding IsValid, Converter={StaticResource BoolToOpacityConverter}}"
Cursor="Hand"
ToolTip="{Binding Name}"
Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}">
<Border.InputBindings>
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding DataContext.ExecuteToolCommand, RelativeSource={RelativeSource AncestorType=Window}}"
CommandParameter="{Binding}"/>
</Border.InputBindings>
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="运行"
Command="{Binding PlacementTarget.Tag.ExecuteToolCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"/>
<MenuItem Header="编辑工具"
Command="{Binding PlacementTarget.Tag.EditToolCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}">
<MenuItem.Style>
<Style TargetType="MenuItem">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsGroup}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</MenuItem.Style>
</MenuItem>
<MenuItem Header="编辑组合"
Command="{Binding PlacementTarget.Tag.EditGroupCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}">
<MenuItem.Style>
<Style TargetType="MenuItem">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsGroup}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</MenuItem.Style>
</MenuItem>
<Separator/>
<MenuItem Header="删除"
Command="{Binding PlacementTarget.Tag.DeleteToolCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"/>
</ContextMenu>
</Border.ContextMenu>
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid HorizontalAlignment="Center" Margin="0,0,0,4">
<!-- FontAwesome 图标IconCode 有值时显示) -->
<fa:IconBlock Icon="{Binding IconCode, Converter={StaticResource StringToIconCharConverter}}"
FontSize="28"
Foreground="{DynamicResource Theme.Accent}"
HorizontalAlignment="Center">
<fa:IconBlock.Style>
<Style TargetType="fa:IconBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IconCode}" Value="">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</fa:IconBlock.Style>
</fa:IconBlock>
<!-- 首字母回退IconCode 为空时显示) -->
<TextBlock FontSize="28"
Foreground="{DynamicResource Theme.Accent}"
HorizontalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Text" Value="{Binding Name, Converter={StaticResource FirstCharConverter}}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IconCode}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
<TextBlock Text="{Binding Name}"
FontSize="12"
Foreground="{DynamicResource Theme.Foreground}"
HorizontalAlignment="Center"
TextTrimming="CharacterEllipsis"
MaxWidth="120"/>
</StackPanel>
<!-- 组合角标 -->
<fa:IconBlock Icon="Cubes" FontSize="11"
Foreground="{DynamicResource Theme.Accent}"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,4,6,0">
<fa:IconBlock.Style>
<Style TargetType="fa:IconBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsGroup}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</fa:IconBlock.Style>
</fa:IconBlock>
<!-- 自启动角标 -->
<fa:IconBlock Icon="Rocket" FontSize="10"
Foreground="{DynamicResource Theme.Accent}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="6,4,0,0">
<fa:IconBlock.Style>
<Style TargetType="fa:IconBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding AutoRunOnStart}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</fa:IconBlock.Style>
</fa:IconBlock>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="3"/>
<RowDefinition Height="120"/>
</Grid.RowDefinitions>
<!-- ──────────────── 内容区 ──────────────── -->
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- ─── 左侧边栏 ─── -->
<Border Grid.Column="0" Background="{DynamicResource Theme.SidebarBackground}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="42"/>
<RowDefinition Height="42"/>
<RowDefinition Height="45"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0"
x:Name="CategoryListBox"
ItemsSource="{Binding Categories}"
SelectedItem="{Binding SelectedCategory}"
Background="Transparent"
BorderThickness="0"
Foreground="{DynamicResource Theme.Foreground}"
SelectionMode="Single">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="16,10"/>
<Setter Property="Tag" Value="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="3,0,0,0"
Padding="{TemplateBinding Padding}"
Tag="{TemplateBinding Tag}">
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="编辑"
Command="{Binding PlacementTarget.Tag.EditCategoryCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"/>
<MenuItem Header="删除"
Command="{Binding PlacementTarget.Tag.DeleteCategoryCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"/>
</ContextMenu>
</Border.ContextMenu>
<TextBlock Text="{Binding Name}"
Foreground="{DynamicResource Theme.Foreground}"
FontSize="14"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="#20FFFFFF"/>
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource Theme.Accent}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="#10FFFFFF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<!-- 分类管理按钮 -->
<Button Grid.Row="1"
Command="{Binding AddCategoryCommand}"
Background="Transparent"
BorderThickness="1"
BorderBrush="{DynamicResource Theme.CardBorder}"
Foreground="{DynamicResource Theme.Foreground}"
FontSize="12"
Height="35" Margin="10,0,10,3"
Cursor="Hand">
<StackPanel Orientation="Horizontal">
<TextBlock Text="+" FontSize="16" Margin="0,0,8,0"
VerticalAlignment="Center"/>
<TextBlock Text="添加分类" VerticalAlignment="Center"/>
</StackPanel>
</Button>
<Button Grid.Row="2"
Command="{Binding ToggleAutoStartCommand}"
Background="Transparent"
BorderThickness="1"
BorderBrush="{DynamicResource Theme.CardBorder}"
Foreground="{DynamicResource Theme.Foreground}"
FontSize="12"
Height="35" Margin="10,0,10,3"
Cursor="Hand">
<Button.Resources>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="⊗ 开机自启: 关"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsAutoStart}" Value="True">
<Setter Property="Text" Value="✔ 开机自启: 开"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Resources>
<TextBlock VerticalAlignment="Center" TextAlignment="Center"/>
</Button>
<Button Grid.Row="3"
Command="{Binding ToggleThemeCommand}"
Background="Transparent"
BorderThickness="1"
BorderBrush="{DynamicResource Theme.CardBorder}"
Foreground="{DynamicResource Theme.Foreground}"
FontSize="12"
Height="35" Margin="10,0,10,10"
Cursor="Hand">
<StackPanel Orientation="Horizontal">
<TextBlock Text="◐" FontSize="16" Margin="0,0,8,0"
VerticalAlignment="Center"/>
<TextBlock Text="切换主题" VerticalAlignment="Center"/>
</StackPanel>
</Button>
</Grid>
</Border>
<!-- ─── 右侧主体区 ─── -->
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="{DynamicResource Theme.Background}"
BorderBrush="{DynamicResource Theme.CardBorder}"
BorderThickness="0,0,0,1">
<Grid Margin="12,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"
Background="{DynamicResource Theme.InputBackground}"
Foreground="{DynamicResource Theme.Foreground}"
BorderBrush="{DynamicResource Theme.InputBorder}"
BorderThickness="1"
FontSize="14"
VerticalContentAlignment="Center"
Height="32"
Margin="0,0,12,0"
Padding="8,0"/>
<Button Grid.Column="1"
Content="+ 添加工具"
Command="{Binding AddToolCommand}"
Background="{DynamicResource Theme.ButtonBackground}"
Foreground="{DynamicResource Theme.ButtonForeground}"
BorderThickness="0"
FontSize="12"
Height="32"
Cursor="Hand"
Margin="0,0,6,0">
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="4"/>
</Style>
</Button.Resources>
</Button>
<Button Grid.Column="2"
Content="+ 添加组合"
Command="{Binding AddGroupCommand}"
Background="{DynamicResource Theme.Accent}"
Foreground="{DynamicResource Theme.ButtonForeground}"
BorderThickness="0"
FontSize="12"
Height="32"
Cursor="Hand">
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="4"/>
</Style>
</Button.Resources>
</Button>
</Grid>
</Border>
<ScrollViewer Grid.Row="1"
VerticalScrollBarVisibility="Auto"
Background="{DynamicResource Theme.Background}">
<ItemsControl ItemsSource="{Binding FilteredTools}"
Margin="8">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<StaticResource ResourceKey="ToolCardTemplate"/>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Grid>
<!-- ──────────────── 分隔线 ──────────────── -->
<Border Grid.Row="1" Background="{DynamicResource Theme.CardBorder}"/>
<!-- ──────────────── 底部日志栏 ──────────────── -->
<Border Grid.Row="2" Background="{DynamicResource Theme.LogBackground}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0"
Background="{DynamicResource Theme.SidebarBackground}"
BorderBrush="{DynamicResource Theme.CardBorder}"
BorderThickness="0,0,0,1">
<Grid Margin="10,0">
<TextBlock Text="运行日志"
Foreground="{DynamicResource Theme.Foreground}"
FontSize="12" FontWeight="SemiBold"
VerticalAlignment="Center"/>
<Button Content="清空日志"
Command="{Binding ClearLogsCommand}"
Background="Transparent"
Foreground="{DynamicResource Theme.TextSecondary}"
BorderThickness="0"
FontSize="11"
HorizontalAlignment="Right"
Height="22"
Cursor="Hand"/>
</Grid>
</Border>
<ListBox Grid.Row="1"
x:Name="LogListBox"
ItemsSource="{Binding Logs}"
Background="Transparent"
BorderThickness="0"
Foreground="{DynamicResource Theme.Foreground}"
FontFamily="Consolas"
FontSize="12"
VirtualizingPanel.IsVirtualizing="True">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0,1,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type models:LogEntry}">
<TextBlock Text="{Binding .}" Padding="8,1"
Foreground="{DynamicResource Theme.Foreground}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</Grid>
</Window>