add:新设置

This commit is contained in:
2026-02-07 14:49:52 +08:00
parent fa7caf3592
commit 840eca88c8
5 changed files with 705 additions and 604 deletions
@@ -10,9 +10,6 @@ using Media = System.Windows.Media;
namespace Ink_Canvas.Windows.SettingsViews
{
/// <summary>
/// 辅助类:用于在新设置面板中调用 MainWindow 中已有的设置处理方法
/// </summary>
public static class MainWindowSettingsHelper
{
private static MainWindow GetMainWindow()
@@ -88,165 +88,6 @@
</StackPanel>
</Border>
<!-- 更新设置 -->
<Border Margin="0,25,0,0" BorderBrush="#e6e6e6" BorderThickness="1.25,1.25,1.25,4" CornerRadius="8">
<StackPanel Orientation="Vertical">
<Grid Height="54">
<StackPanel Orientation="Vertical" Margin="18,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="自动检查更新" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="定期检查是否有新版本可用" HorizontalAlignment="Left"/>
</StackPanel>
<Border x:Name="ToggleSwitchIsAutoUpdate" Style="{StaticResource ToggleSwitchStyle}" Background="#3584e4" Tag="IsAutoUpdate" MouseLeftButtonDown="ToggleSwitch_Click">
<Border Width="19" Height="19" Background="White" CornerRadius="10" HorizontalAlignment="Right" VerticalAlignment="Center">
<Border.Effect>
<DropShadowEffect BlurRadius="4" Direction="-45" Color="Black" Opacity="0.3" ShadowDepth="0"/>
</Border.Effect>
</Border>
</Border>
</Grid>
<Border Height="1" Background="#ebebeb"/>
<Grid Height="54">
<StackPanel Orientation="Vertical" Margin="18,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="静默更新" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="在软件不使用时自动安装更新,无需手动操作" HorizontalAlignment="Left"/>
</StackPanel>
<Border x:Name="ToggleSwitchIsAutoUpdateWithSilence" Style="{StaticResource ToggleSwitchStyle}" Background="#3584e4" Tag="IsAutoUpdateWithSilence" MouseLeftButtonDown="ToggleSwitch_Click">
<Border Width="19" Height="19" Background="White" CornerRadius="10" HorizontalAlignment="Right" VerticalAlignment="Center">
<Border.Effect>
<DropShadowEffect BlurRadius="4" Direction="-45" Color="Black" Opacity="0.3" ShadowDepth="0"/>
</Border.Effect>
</Border>
</Border>
</Grid>
<Border Height="1" Background="#ebebeb"/>
<Grid Height="54">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Margin="18,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Column="0" MaxWidth="350">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="更新通道" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="选择更新通道:稳定版提供可靠更新,测试版提供新功能抢先体验" HorizontalAlignment="Left" TextWrapping="Wrap"/>
</StackPanel>
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,15,0" Grid.Column="1">
<Border x:Name="UpdateChannelReleaseBorder" Padding="13,7" CornerRadius="8" Background="#e1e1e1" Cursor="Hand" Tag="UpdateChannel_Release" Margin="0,0,8,8" MouseLeftButtonDown="OptionButton_Click">
<TextBlock Foreground="#2e3436" FontSize="14" FontWeight="Bold" Text="稳定版"/>
</Border>
<Border x:Name="UpdateChannelPreviewBorder" Padding="13,7" CornerRadius="8" Cursor="Hand" Tag="UpdateChannel_Preview" Margin="0,0,8,8" MouseLeftButtonDown="OptionButton_Click">
<TextBlock Foreground="#2e3436" FontSize="14" Text="预览版"/>
</Border>
<Border x:Name="UpdateChannelBetaBorder" Padding="13,7" CornerRadius="8" Cursor="Hand" Tag="UpdateChannel_Beta" Margin="0,0,8,8" MouseLeftButtonDown="OptionButton_Click">
<TextBlock Foreground="#2e3436" FontSize="14" Text="测试版"/>
</Border>
</WrapPanel>
</Grid>
<Border Height="1" Background="#ebebeb"/>
<Grid Height="54">
<StackPanel Orientation="Vertical" Margin="18,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="手动更新" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="点击后立即检查并下载最新版本" HorizontalAlignment="Left"/>
</StackPanel>
<Button x:Name="ManualUpdateButton" Content="手动更新" Width="120" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,15,0" Padding="12,6" Click="ManualUpdateButton_Click"/>
</Grid>
<Border Height="1" Background="#ebebeb"/>
<Grid Height="54">
<StackPanel Orientation="Vertical" Margin="18,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="版本修复" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="根据当前选择的通道下载最新版本并执行安装,可用于修复损坏的安装" HorizontalAlignment="Left"/>
</StackPanel>
<Button x:Name="FixVersionButton" Content="版本修复" Width="120" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,15,0" Padding="12,6" Click="FixVersionButton_Click"/>
</Grid>
<Border Height="1" Background="#ebebeb"/>
<Grid Height="54">
<StackPanel Orientation="Vertical" Margin="18,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="历史版本回滚" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="回滚到之前的版本" HorizontalAlignment="Left"/>
</StackPanel>
<Button x:Name="HistoryRollbackButton" Content="历史版本回滚" Width="120" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,15,0" Padding="12,6" Click="HistoryRollbackButton_Click"/>
</Grid>
<Border Height="1" Background="#ebebeb"/>
<Grid Margin="18,12,15,12" x:Name="AutoUpdateTimePeriodBlock">
<StackPanel>
<TextBlock Text="静默更新时间段" FontSize="15" FontWeight="Bold" Foreground="#2e3436" Margin="0,0,0,12"/>
<StackPanel>
<StackPanel Orientation="Vertical" Margin="0,0,0,12">
<TextBlock Text="起始时间" FontSize="14" Foreground="#2e3436" Margin="0,0,0,8"/>
<ComboBox x:Name="AutoUpdateWithSilenceStartTimeComboBox"
Style="{StaticResource ComboBoxStyle}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
HorizontalAlignment="Left"
Width="150"
SelectedIndex="6"
SelectionChanged="AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged">
<ComboBoxItem Content="00:00" Tag="00"/>
<ComboBoxItem Content="01:00" Tag="01"/>
<ComboBoxItem Content="02:00" Tag="02"/>
<ComboBoxItem Content="03:00" Tag="03"/>
<ComboBoxItem Content="04:00" Tag="04"/>
<ComboBoxItem Content="05:00" Tag="05"/>
<ComboBoxItem Content="06:00" Tag="06" IsSelected="True"/>
<ComboBoxItem Content="07:00" Tag="07"/>
<ComboBoxItem Content="08:00" Tag="08"/>
<ComboBoxItem Content="09:00" Tag="09"/>
<ComboBoxItem Content="10:00" Tag="10"/>
<ComboBoxItem Content="11:00" Tag="11"/>
<ComboBoxItem Content="12:00" Tag="12"/>
<ComboBoxItem Content="13:00" Tag="13"/>
<ComboBoxItem Content="14:00" Tag="14"/>
<ComboBoxItem Content="15:00" Tag="15"/>
<ComboBoxItem Content="16:00" Tag="16"/>
<ComboBoxItem Content="17:00" Tag="17"/>
<ComboBoxItem Content="18:00" Tag="18"/>
<ComboBoxItem Content="19:00" Tag="19"/>
<ComboBoxItem Content="20:00" Tag="20"/>
<ComboBoxItem Content="21:00" Tag="21"/>
<ComboBoxItem Content="22:00" Tag="22"/>
<ComboBoxItem Content="23:00" Tag="23"/>
</ComboBox>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="0,0,0,0">
<TextBlock Text="终止时间" FontSize="14" Foreground="#2e3436" Margin="0,0,0,8"/>
<ComboBox x:Name="AutoUpdateWithSilenceEndTimeComboBox"
Style="{StaticResource ComboBoxStyle}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
HorizontalAlignment="Left"
Width="150"
SelectedIndex="22"
SelectionChanged="AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged">
<ComboBoxItem Content="00:00" Tag="00"/>
<ComboBoxItem Content="01:00" Tag="01"/>
<ComboBoxItem Content="02:00" Tag="02"/>
<ComboBoxItem Content="03:00" Tag="03"/>
<ComboBoxItem Content="04:00" Tag="04"/>
<ComboBoxItem Content="05:00" Tag="05"/>
<ComboBoxItem Content="06:00" Tag="06"/>
<ComboBoxItem Content="07:00" Tag="07"/>
<ComboBoxItem Content="08:00" Tag="08"/>
<ComboBoxItem Content="09:00" Tag="09"/>
<ComboBoxItem Content="10:00" Tag="10"/>
<ComboBoxItem Content="11:00" Tag="11"/>
<ComboBoxItem Content="12:00" Tag="12"/>
<ComboBoxItem Content="13:00" Tag="13"/>
<ComboBoxItem Content="14:00" Tag="14"/>
<ComboBoxItem Content="15:00" Tag="15"/>
<ComboBoxItem Content="16:00" Tag="16"/>
<ComboBoxItem Content="17:00" Tag="17"/>
<ComboBoxItem Content="18:00" Tag="18"/>
<ComboBoxItem Content="19:00" Tag="19"/>
<ComboBoxItem Content="20:00" Tag="20"/>
<ComboBoxItem Content="21:00" Tag="21"/>
<ComboBoxItem Content="22:00" Tag="22" IsSelected="True"/>
<ComboBoxItem Content="23:00" Tag="23"/>
</ComboBox>
</StackPanel>
</StackPanel>
<TextBlock Margin="0,8,0,0" Text="若终止时间小于起始时间,即将终止时间视为第二天的时间。若起始时间与终止时间相同,即视为全天候时间。"
TextWrapping="Wrap" Foreground="#9a9996" FontSize="11"/>
</StackPanel>
</Grid>
</StackPanel>
</Border>
<!-- 启动设置 -->
<Border Margin="0,25,0,0" BorderBrush="#e6e6e6" BorderThickness="1.25,1.25,1.25,4" CornerRadius="8">
<StackPanel Orientation="Vertical">
@@ -86,54 +86,6 @@ namespace Ink_Canvas.Windows.SettingsViews
try
{
// 自动更新设置
var toggleSwitchIsAutoUpdate = FindToggleSwitch("ToggleSwitchIsAutoUpdate");
if (toggleSwitchIsAutoUpdate != null)
{
bool isAutoUpdate = MainWindow.Settings.Startup.IsAutoUpdate;
SetToggleSwitchState(toggleSwitchIsAutoUpdate, isAutoUpdate);
}
// 静默更新设置
var toggleSwitchIsAutoUpdateWithSilence = FindToggleSwitch("ToggleSwitchIsAutoUpdateWithSilence");
if (toggleSwitchIsAutoUpdateWithSilence != null)
{
bool isAutoUpdateWithSilence = MainWindow.Settings.Startup.IsAutoUpdateWithSilence;
SetToggleSwitchState(toggleSwitchIsAutoUpdateWithSilence, isAutoUpdateWithSilence);
toggleSwitchIsAutoUpdateWithSilence.Visibility = MainWindow.Settings.Startup.IsAutoUpdate ? Visibility.Visible : Visibility.Collapsed;
}
// 静默更新时间段
if (AutoUpdateTimePeriodBlock != null)
{
AutoUpdateTimePeriodBlock.Visibility =
(MainWindow.Settings.Startup.IsAutoUpdateWithSilence && MainWindow.Settings.Startup.IsAutoUpdate) ?
Visibility.Visible : Visibility.Collapsed;
}
// 设置时间选择器
if (AutoUpdateWithSilenceStartTimeComboBox != null)
{
var startTime = MainWindow.Settings.Startup.AutoUpdateWithSilenceStartTime ?? "06:00";
var startItem = AutoUpdateWithSilenceStartTimeComboBox.Items.Cast<ComboBoxItem>()
.FirstOrDefault(item => item.Tag?.ToString() == startTime.Replace(":", ""));
if (startItem != null)
{
AutoUpdateWithSilenceStartTimeComboBox.SelectedItem = startItem;
}
}
if (AutoUpdateWithSilenceEndTimeComboBox != null)
{
var endTime = MainWindow.Settings.Startup.AutoUpdateWithSilenceEndTime ?? "22:00";
var endItem = AutoUpdateWithSilenceEndTimeComboBox.Items.Cast<ComboBoxItem>()
.FirstOrDefault(item => item.Tag?.ToString() == endTime.Replace(":", ""));
if (endItem != null)
{
AutoUpdateWithSilenceEndTimeComboBox.SelectedItem = endItem;
}
}
// 开机时运行
var toggleSwitchRunAtStartup = FindToggleSwitch("ToggleSwitchRunAtStartup");
if (toggleSwitchRunAtStartup != null)
@@ -179,20 +131,6 @@ namespace Ink_Canvas.Windows.SettingsViews
SetToggleSwitchState(toggleSwitchUIAccessTopMost, MainWindow.Settings.Advanced.EnableUIAccessTopMost);
}
// 更新通道
if (MainWindow.Settings.Startup.UpdateChannel == UpdateChannel.Release)
{
UpdateUpdateChannelButtons(UpdateChannel.Release);
}
else if (MainWindow.Settings.Startup.UpdateChannel == UpdateChannel.Preview)
{
UpdateUpdateChannelButtons(UpdateChannel.Preview);
}
else
{
UpdateUpdateChannelButtons(UpdateChannel.Beta);
}
// 仅PPT模式
var toggleSwitchMode = FindToggleSwitch("ToggleSwitchMode");
if (toggleSwitchMode != null && MainWindow.Settings.ModeSettings != null)
@@ -241,10 +179,6 @@ namespace Ink_Canvas.Windows.SettingsViews
{
switch (tag)
{
case "IsAutoUpdate":
return MainWindow.Settings.Startup?.IsAutoUpdate ?? false;
case "IsAutoUpdateWithSilence":
return MainWindow.Settings.Startup?.IsAutoUpdateWithSilence ?? false;
case "RunAtStartup":
// 检查启动项是否存在
return System.IO.File.Exists(
@@ -290,33 +224,6 @@ namespace Ink_Canvas.Windows.SettingsViews
switch (tag)
{
case "IsAutoUpdate":
// 直接调用 MainWindow 中的方法
MainWindowSettingsHelper.InvokeToggleSwitchToggled("ToggleSwitchIsAutoUpdate", newState);
// 更新UI状态
var toggleSwitchIsAutoUpdateWithSilence = FindToggleSwitch("ToggleSwitchIsAutoUpdateWithSilence");
if (toggleSwitchIsAutoUpdateWithSilence != null)
{
toggleSwitchIsAutoUpdateWithSilence.Visibility = newState ? Visibility.Visible : Visibility.Collapsed;
}
if (AutoUpdateTimePeriodBlock != null)
{
AutoUpdateTimePeriodBlock.Visibility =
(MainWindow.Settings.Startup.IsAutoUpdateWithSilence && MainWindow.Settings.Startup.IsAutoUpdate) ?
Visibility.Visible : Visibility.Collapsed;
}
break;
case "IsAutoUpdateWithSilence":
// 直接调用 MainWindow 中的方法
MainWindowSettingsHelper.InvokeToggleSwitchToggled("ToggleSwitchIsAutoUpdateWithSilence", newState);
// 更新UI状态
if (AutoUpdateTimePeriodBlock != null)
{
AutoUpdateTimePeriodBlock.Visibility = newState ? Visibility.Visible : Visibility.Collapsed;
}
break;
case "RunAtStartup":
// 直接调用 MainWindow 中的方法
MainWindowSettingsHelper.InvokeToggleSwitchToggled("ToggleSwitchRunAtStartup", newState);
@@ -376,156 +283,6 @@ namespace Ink_Canvas.Windows.SettingsViews
}
}
/// <summary>
/// 选项按钮点击事件处理
/// </summary>
private void OptionButton_Click(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
var border = sender as Border;
if (border == null) return;
string tag = border.Tag?.ToString();
if (string.IsNullOrEmpty(tag)) return;
switch (tag)
{
case "UpdateChannel_Release":
// 选择稳定版
MainWindowSettingsHelper.UpdateSettingDirectly(() =>
{
MainWindow.Settings.Startup.UpdateChannel = UpdateChannel.Release;
}, "UpdateChannelSelector");
// 调用 MainWindow 中的方法
MainWindowSettingsHelper.InvokeMainWindowMethod("UpdateChannelSelector_Checked",
new System.Windows.Controls.RadioButton { Tag = "Release" }, e);
// 更新UI状态
UpdateUpdateChannelButtons(UpdateChannel.Release);
break;
case "UpdateChannel_Preview":
// 选择预览版
MainWindowSettingsHelper.UpdateSettingDirectly(() =>
{
MainWindow.Settings.Startup.UpdateChannel = UpdateChannel.Preview;
}, "UpdateChannelSelector");
// 调用 MainWindow 中的方法
MainWindowSettingsHelper.InvokeMainWindowMethod("UpdateChannelSelector_Checked",
new System.Windows.Controls.RadioButton { Tag = "Preview" }, e);
// 更新UI状态
UpdateUpdateChannelButtons(UpdateChannel.Preview);
break;
case "UpdateChannel_Beta":
// 选择测试版
MainWindowSettingsHelper.UpdateSettingDirectly(() =>
{
MainWindow.Settings.Startup.UpdateChannel = UpdateChannel.Beta;
}, "UpdateChannelSelector");
// 调用 MainWindow 中的方法
MainWindowSettingsHelper.InvokeMainWindowMethod("UpdateChannelSelector_Checked",
new System.Windows.Controls.RadioButton { Tag = "Beta" }, e);
// 更新UI状态
UpdateUpdateChannelButtons(UpdateChannel.Beta);
break;
}
}
/// <summary>
/// 更新更新通道按钮状态
/// </summary>
private void UpdateUpdateChannelButtons(UpdateChannel selectedChannel)
{
try
{
bool isDarkTheme = ThemeHelper.IsDarkTheme;
var selectedBrush = isDarkTheme ? new SolidColorBrush(Color.FromRgb(25, 25, 25)) : new SolidColorBrush(Color.FromRgb(225, 225, 225));
var unselectedBrush = new SolidColorBrush(Colors.Transparent);
if (UpdateChannelReleaseBorder != null)
{
bool isSelected = selectedChannel == UpdateChannel.Release;
UpdateChannelReleaseBorder.Background = isSelected ? selectedBrush : unselectedBrush;
var textBlock = UpdateChannelReleaseBorder.Child as TextBlock;
if (textBlock != null)
{
textBlock.FontWeight = isSelected ? FontWeights.Bold : FontWeights.Normal;
textBlock.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
}
if (UpdateChannelPreviewBorder != null)
{
bool isSelected = selectedChannel == UpdateChannel.Preview;
UpdateChannelPreviewBorder.Background = isSelected ? selectedBrush : unselectedBrush;
var textBlock = UpdateChannelPreviewBorder.Child as TextBlock;
if (textBlock != null)
{
textBlock.FontWeight = isSelected ? FontWeights.Bold : FontWeights.Normal;
textBlock.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
}
if (UpdateChannelBetaBorder != null)
{
bool isSelected = selectedChannel == UpdateChannel.Beta;
UpdateChannelBetaBorder.Background = isSelected ? selectedBrush : unselectedBrush;
var textBlock = UpdateChannelBetaBorder.Child as TextBlock;
if (textBlock != null)
{
textBlock.FontWeight = isSelected ? FontWeights.Bold : FontWeights.Normal;
textBlock.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"更新更新通道按钮状态时出错: {ex.Message}");
}
}
/// <summary>
/// 手动更新按钮点击事件
/// </summary>
private async void ManualUpdateButton_Click(object sender, RoutedEventArgs e)
{
MainWindowSettingsHelper.InvokeMainWindowMethod("ManualUpdateButton_Click", sender, e);
}
/// <summary>
/// 版本修复按钮点击事件
/// </summary>
private async void FixVersionButton_Click(object sender, RoutedEventArgs e)
{
MainWindowSettingsHelper.InvokeMainWindowMethod("FixVersionButton_Click", sender, e);
}
/// <summary>
/// 历史版本回滚按钮点击事件
/// </summary>
private void HistoryRollbackButton_Click(object sender, RoutedEventArgs e)
{
// 查找 MainWindow 中的历史版本回滚方法
MainWindowSettingsHelper.InvokeMainWindowMethod("HistoryRollbackButton_Click", sender, e);
}
/// <summary>
/// ComboBox选择变化事件处理
/// </summary>
private void AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isLoaded) return;
// 直接调用 MainWindow 中的方法
MainWindowSettingsHelper.InvokeComboBoxSelectionChanged("AutoUpdateWithSilenceStartTimeComboBox", AutoUpdateWithSilenceStartTimeComboBox?.SelectedItem);
}
private void AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isLoaded) return;
// 直接调用 MainWindow 中的方法
MainWindowSettingsHelper.InvokeComboBoxSelectionChanged("AutoUpdateWithSilenceEndTimeComboBox", AutoUpdateWithSilenceEndTimeComboBox?.SelectedItem);
}
/// <summary>
/// 应用主题
@@ -534,31 +291,6 @@ namespace Ink_Canvas.Windows.SettingsViews
{
try
{
bool isDarkTheme = ThemeHelper.IsDarkTheme;
if (MainWindow.Settings?.Startup != null)
{
UpdateUpdateChannelButtons(MainWindow.Settings.Startup.UpdateChannel);
}
// 更新按钮
if (ManualUpdateButton != null)
{
ManualUpdateButton.Background = ThemeHelper.GetButtonBackgroundBrush();
ManualUpdateButton.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
if (FixVersionButton != null)
{
FixVersionButton.Background = ThemeHelper.GetButtonBackgroundBrush();
FixVersionButton.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
if (HistoryRollbackButton != null)
{
HistoryRollbackButton.Background = ThemeHelper.GetButtonBackgroundBrush();
HistoryRollbackButton.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
// 使用 ThemeHelper 递归更新其他元素
ThemeHelper.ApplyThemeToControl(this);
if (_isLoaded)
{
@@ -5,9 +5,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Ink_Canvas.Windows.SettingsViews"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:mdxam="clr-namespace:MdXaml;assembly=MdXaml"
mc:Ignorable="d"
d:DesignHeight="950" d:DesignWidth="640">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ComboBoxStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="ToggleSwitchStyle" TargetType="Border">
<Setter Property="Width" Value="48"/>
<Setter Property="Height" Value="25"/>
@@ -18,95 +23,49 @@
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="Margin" Value="0,0,15,0"/>
</Style>
<Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<EventSetter Event="PreviewMouseDown" Handler="ScrollbarThumb_MouseDown"/>
<EventSetter Event="PreviewMouseUp" Handler="ScrollbarThumb_MouseUp"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Name="ScrollbarThumbEx"
SnapsToDevicePixels="True"
Background="#c3c3c3"
Opacity="0.5"
CornerRadius="1.5"
Height="{TemplateBinding Height}"
Width="3" HorizontalAlignment="Center"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ScrollBar}">
<EventSetter Event="Scroll" Handler="ScrollBar_Scroll"/>
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
<Setter Property="Width" Value="8"/>
<Setter Property="Margin" Value="-6 3 0 0" />
<Setter Property="MinWidth" Value="{Binding Height, RelativeSource={RelativeSource Self}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="ScrollbarGrid" SnapsToDevicePixels="true">
<Border Width="3" CornerRadius="1.5" Background="#e0e0e0" Opacity="0" IsHitTestVisible="False" Margin="0 4 -2 4" x:Name="ScrollBarBorderTrackBackground"/>
<Border Padding="0 4" Background="Transparent" MouseEnter="ScrollBarTrack_MouseEnter"
MouseLeave="ScrollBarTrack_MouseLeave">
<Track x:Name="PART_Track"
IsDirectionReversed="true"
IsEnabled="True"
Width="6"
Margin="0,0,0,0"
HorizontalAlignment="Right">
<Track.DecreaseRepeatButton>
<RepeatButton Opacity="0" Command="{x:Static ScrollBar.PageUpCommand}" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Opacity="0" Command="{x:Static ScrollBar.PageDownCommand}" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb }" />
</Track.Thumb>
</Track>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ScrollViewer ScrollChanged="ScrollViewerEx_ScrollChanged" IsManipulationEnabled="True" Name="UpdateCenterScrollViewerEx" IsDeferredScrollingEnabled="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Disabled" IsTabStop="False" TabIndex="-1" Margin="0,0,2,2">
<StackPanel Margin="60,24,60,24">
<TextBlock Foreground="#2e3436" FontSize="28" FontWeight="Bold" Text="InkCanvasForClass 更新" Margin="0,0,0,24"/>
<StackPanel Margin="60,12,60,24">
<TextBlock Foreground="#2e3436" FontSize="28" FontWeight="Bold" Text="更新中心" Margin="0,0,0,24"/>
<Border BorderBrush="#e6e6e6" BorderThickness="1" CornerRadius="8" Padding="20" Background="#FAFAFA" Margin="0,0,0,20">
<StackPanel Orientation="Horizontal" Margin="0,0,0,20">
<Border x:Name="TabUpdate" Padding="20,12" CornerRadius="8,8,0,0" Cursor="Hand" MouseLeftButtonDown="Tab_Click" Tag="Update" Background="#e1e1e1">
<TextBlock Foreground="#2e3436" FontSize="16" FontWeight="Bold" Text="更新"/>
</Border>
<Border x:Name="TabRollback" Padding="20,12" CornerRadius="8,8,0,0" Cursor="Hand" MouseLeftButtonDown="Tab_Click" Tag="Rollback" Background="Transparent" Margin="2,0,0,0">
<TextBlock Foreground="#2e3436" FontSize="16" Text="回滚"/>
</Border>
<Border x:Name="TabSettings" Padding="20,12" CornerRadius="8,8,0,0" Cursor="Hand" MouseLeftButtonDown="Tab_Click" Tag="Settings" Background="Transparent" Margin="2,0,0,0">
<TextBlock Foreground="#2e3436" FontSize="16" Text="设置"/>
</Border>
</StackPanel>
<Border BorderBrush="#e6e6e6" BorderThickness="1.25,1.25,1.25,4" CornerRadius="0,8,8,8" Background="#FAFAFA">
<StackPanel>
<StackPanel x:Name="UpdateTabContent" Margin="18,18,18,18">
<Border BorderBrush="#e6e6e6" BorderThickness="1" CornerRadius="8" Padding="20" Background="#FFFFFF" Margin="0,0,0,20">
<StackPanel>
<TextBlock Name="UpdateStatusText" Foreground="#2e3436" FontSize="18" FontWeight="SemiBold" Text="正在检查更新..." TextWrapping="Wrap" Margin="0,0,0,8"/>
<TextBlock Name="LastCheckTimeText" Foreground="#878787" FontSize="14" Text="上次检查时间: 从未" TextWrapping="Wrap"/>
</StackPanel>
</Border>
<StackPanel Orientation="Horizontal" Margin="0,0,0,24" VerticalAlignment="Center">
<TextBlock Name="LastCheckTimeText" Foreground="#878787" FontSize="14" Text="上次检查时间: 从未" TextWrapping="Wrap" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<TextBlock Name="CurrentVersionText" Foreground="#878787" FontSize="14" Text="当前版本: 正在获取..." TextWrapping="Wrap" VerticalAlignment="Center"/>
<ui:ProgressRing Name="LoadingSpinner" Width="16" Height="16" IsActive="False" Margin="12,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,24">
<Button Name="CheckUpdateButton" Content="检查更新" HorizontalAlignment="Left" Padding="20,10" FontSize="14" Cursor="Hand" Click="CheckUpdateButton_Click" Background="#F3F3F3" Foreground="#2e3436" BorderThickness="1" BorderBrush="#E1E1E1" Margin="0,0,12,0">
<Button Name="CheckUpdateButton" Content="检查更新" HorizontalAlignment="Left" Padding="20,10" FontSize="14" Cursor="Hand" Click="CheckUpdateButton_Click" Background="#F3F3F3" Foreground="#2e3436" BorderThickness="1" BorderBrush="#E1E1E1" Margin="0,8,0,0">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4" Padding="{TemplateBinding Padding}">
<StackPanel Orientation="Horizontal">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Path Name="ChevronIcon" Data="M 0 0 L 4 4 L 0 8" Stroke="{TemplateBinding Foreground}" StrokeThickness="1.5" Margin="8,0,0,0" VerticalAlignment="Center" Visibility="Collapsed"/>
</StackPanel>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</Border>
<StackPanel Name="UpdateAvailablePanel" Visibility="Collapsed" Margin="0,0,0,24">
<StackPanel Name="UpdateAvailablePanel" Visibility="Collapsed" Margin="0,0,0,20">
<Border BorderBrush="#e6e6e6" BorderThickness="1" CornerRadius="8" Padding="16" Background="#F9F9F9">
<StackPanel>
<TextBlock Foreground="#2e3436" FontSize="16" FontWeight="SemiBold" Text="可用更新" Margin="0,0,0,8"/>
@@ -123,6 +82,192 @@
</StackPanel>
</Border>
</StackPanel>
<Border BorderBrush="#e6e6e6" BorderThickness="1" CornerRadius="8" Padding="16" Background="#FFFFFF" Margin="0,0,0,20">
<StackPanel>
<TextBlock Foreground="#2e3436" FontSize="16" FontWeight="SemiBold" Text="更新日志" Margin="0,0,0,12"/>
<ScrollViewer MaxHeight="300" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<mdxam:MarkdownScrollViewer x:Name="UpdateLogViewer" Markdown="暂无更新日志" />
</ScrollViewer>
</StackPanel>
</Border>
<Grid Height="54">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Column="0" MaxWidth="350">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="更新通道" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="选择更新通道:稳定版提供可靠更新,预览版提供新功能体验,测试版提供新功能抢先体验" HorizontalAlignment="Left" TextWrapping="Wrap"/>
</StackPanel>
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,15,0" Grid.Column="1">
<Border x:Name="UpdateChannelReleaseBorder" Padding="13,7" CornerRadius="8" Background="#e1e1e1" Cursor="Hand" Tag="UpdateChannel_Release" Margin="0,0,8,8" MouseLeftButtonDown="OptionButton_Click">
<TextBlock Foreground="#2e3436" FontSize="14" FontWeight="Bold" Text="稳定版"/>
</Border>
<Border x:Name="UpdateChannelPreviewBorder" Padding="13,7" CornerRadius="8" Cursor="Hand" Tag="UpdateChannel_Preview" Margin="0,0,8,8" MouseLeftButtonDown="OptionButton_Click">
<TextBlock Foreground="#2e3436" FontSize="14" Text="预览版"/>
</Border>
<Border x:Name="UpdateChannelBetaBorder" Padding="13,7" CornerRadius="8" Cursor="Hand" Tag="UpdateChannel_Beta" Margin="0,0,8,8" MouseLeftButtonDown="OptionButton_Click">
<TextBlock Foreground="#2e3436" FontSize="14" Text="测试版"/>
</Border>
</WrapPanel>
</Grid>
</StackPanel>
<StackPanel x:Name="RollbackTabContent" Visibility="Collapsed" Margin="18,18,18,18">
<Border BorderBrush="#e6e6e6" BorderThickness="1" CornerRadius="8" Padding="16" Background="#FFFFFF" Margin="0,0,0,20">
<StackPanel>
<TextBlock Foreground="#2e3436" FontSize="16" FontWeight="SemiBold" Text="历史版本" Margin="0,0,0,12"/>
<ScrollViewer MaxHeight="300" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<mdxam:MarkdownScrollViewer x:Name="HistoryLogViewer" Markdown="正在加载历史版本..." />
</ScrollViewer>
</StackPanel>
</Border>
<Grid Height="54" Margin="0,0,0,20">
<StackPanel Orientation="Vertical" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="选择回滚版本" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="选择要回滚到的历史版本" HorizontalAlignment="Left"/>
</StackPanel>
<ComboBox x:Name="RollbackVersionComboBox"
Style="{StaticResource ComboBoxStyle}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Width="200"
Margin="0,0,15,0"
SelectionChanged="RollbackVersionComboBox_SelectionChanged"/>
</Grid>
<Grid Height="54" Margin="0,0,0,20">
<StackPanel Orientation="Vertical" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="回滚到选中版本" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="回滚到下拉框中选择的版本" HorizontalAlignment="Left"/>
</StackPanel>
<Button x:Name="RollbackButton" Content="回滚" Width="120" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,15,0" Padding="12,6" Click="RollbackButton_Click"/>
</Grid>
<Grid Height="54">
<StackPanel Orientation="Vertical" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="版本修复" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="根据当前选择的通道下载最新版本并执行安装,可用于修复损坏的安装" HorizontalAlignment="Left"/>
</StackPanel>
<Button x:Name="FixVersionButton" Content="版本修复" Width="120" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,15,0" Padding="12,6" Click="FixVersionButton_Click"/>
</Grid>
</StackPanel>
<StackPanel x:Name="SettingsTabContent" Visibility="Collapsed" Margin="18,18,18,18">
<Grid Height="54">
<StackPanel Orientation="Vertical" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="自动检查更新" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="定期检查是否有新版本可用" HorizontalAlignment="Left"/>
</StackPanel>
<Border x:Name="ToggleSwitchIsAutoUpdate" Style="{StaticResource ToggleSwitchStyle}" Background="#3584e4" Tag="IsAutoUpdate" MouseLeftButtonDown="ToggleSwitch_Click">
<Border Width="19" Height="19" Background="White" CornerRadius="10" HorizontalAlignment="Right" VerticalAlignment="Center">
<Border.Effect>
<DropShadowEffect BlurRadius="4" Direction="-45" Color="Black" Opacity="0.3" ShadowDepth="0"/>
</Border.Effect>
</Border>
</Border>
</Grid>
<Border Height="1" Background="#ebebeb" Margin="0,0,0,0"/>
<Grid Height="54" x:Name="AutoUpdateWithSilencePanel">
<StackPanel Orientation="Vertical" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="静默更新" HorizontalAlignment="Left"/>
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="在软件不使用时自动安装更新,无需手动操作" HorizontalAlignment="Left"/>
</StackPanel>
<Border x:Name="ToggleSwitchIsAutoUpdateWithSilence" Style="{StaticResource ToggleSwitchStyle}" Background="#3584e4" Tag="IsAutoUpdateWithSilence" MouseLeftButtonDown="ToggleSwitch_Click">
<Border Width="19" Height="19" Background="White" CornerRadius="10" HorizontalAlignment="Right" VerticalAlignment="Center">
<Border.Effect>
<DropShadowEffect BlurRadius="4" Direction="-45" Color="Black" Opacity="0.3" ShadowDepth="0"/>
</Border.Effect>
</Border>
</Border>
</Grid>
<Border Height="1" Background="#ebebeb" Margin="0,0,0,0" x:Name="AutoUpdateTimePeriodSeparator"/>
<Grid Margin="0,12,0,12" x:Name="AutoUpdateTimePeriodBlock">
<StackPanel>
<TextBlock Text="静默更新时间段" FontSize="15" FontWeight="Bold" Foreground="#2e3436" Margin="0,0,0,12"/>
<StackPanel>
<StackPanel Orientation="Vertical" Margin="0,0,0,12">
<TextBlock Text="起始时间" FontSize="14" Foreground="#2e3436" Margin="0,0,0,8"/>
<ComboBox x:Name="AutoUpdateWithSilenceStartTimeComboBox"
Style="{StaticResource ComboBoxStyle}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
HorizontalAlignment="Left"
Width="150"
SelectedIndex="6"
SelectionChanged="AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged">
<ComboBoxItem Content="00:00" Tag="00"/>
<ComboBoxItem Content="01:00" Tag="01"/>
<ComboBoxItem Content="02:00" Tag="02"/>
<ComboBoxItem Content="03:00" Tag="03"/>
<ComboBoxItem Content="04:00" Tag="04"/>
<ComboBoxItem Content="05:00" Tag="05"/>
<ComboBoxItem Content="06:00" Tag="06" IsSelected="True"/>
<ComboBoxItem Content="07:00" Tag="07"/>
<ComboBoxItem Content="08:00" Tag="08"/>
<ComboBoxItem Content="09:00" Tag="09"/>
<ComboBoxItem Content="10:00" Tag="10"/>
<ComboBoxItem Content="11:00" Tag="11"/>
<ComboBoxItem Content="12:00" Tag="12"/>
<ComboBoxItem Content="13:00" Tag="13"/>
<ComboBoxItem Content="14:00" Tag="14"/>
<ComboBoxItem Content="15:00" Tag="15"/>
<ComboBoxItem Content="16:00" Tag="16"/>
<ComboBoxItem Content="17:00" Tag="17"/>
<ComboBoxItem Content="18:00" Tag="18"/>
<ComboBoxItem Content="19:00" Tag="19"/>
<ComboBoxItem Content="20:00" Tag="20"/>
<ComboBoxItem Content="21:00" Tag="21"/>
<ComboBoxItem Content="22:00" Tag="22"/>
<ComboBoxItem Content="23:00" Tag="23"/>
</ComboBox>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="0,0,0,0">
<TextBlock Text="终止时间" FontSize="14" Foreground="#2e3436" Margin="0,0,0,8"/>
<ComboBox x:Name="AutoUpdateWithSilenceEndTimeComboBox"
Style="{StaticResource ComboBoxStyle}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
HorizontalAlignment="Left"
Width="150"
SelectedIndex="22"
SelectionChanged="AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged">
<ComboBoxItem Content="00:00" Tag="00"/>
<ComboBoxItem Content="01:00" Tag="01"/>
<ComboBoxItem Content="02:00" Tag="02"/>
<ComboBoxItem Content="03:00" Tag="03"/>
<ComboBoxItem Content="04:00" Tag="04"/>
<ComboBoxItem Content="05:00" Tag="05"/>
<ComboBoxItem Content="06:00" Tag="06"/>
<ComboBoxItem Content="07:00" Tag="07"/>
<ComboBoxItem Content="08:00" Tag="08"/>
<ComboBoxItem Content="09:00" Tag="09"/>
<ComboBoxItem Content="10:00" Tag="10"/>
<ComboBoxItem Content="11:00" Tag="11"/>
<ComboBoxItem Content="12:00" Tag="12"/>
<ComboBoxItem Content="13:00" Tag="13"/>
<ComboBoxItem Content="14:00" Tag="14"/>
<ComboBoxItem Content="15:00" Tag="15"/>
<ComboBoxItem Content="16:00" Tag="16"/>
<ComboBoxItem Content="17:00" Tag="17"/>
<ComboBoxItem Content="18:00" Tag="18"/>
<ComboBoxItem Content="19:00" Tag="19"/>
<ComboBoxItem Content="20:00" Tag="20"/>
<ComboBoxItem Content="21:00" Tag="21"/>
<ComboBoxItem Content="22:00" Tag="22" IsSelected="True"/>
<ComboBoxItem Content="23:00" Tag="23"/>
</ComboBox>
</StackPanel>
</StackPanel>
<TextBlock Margin="0,8,0,0" Text="若终止时间小于起始时间,即将终止时间视为第二天的时间。若起始时间与终止时间相同,即视为全天候时间。"
TextWrapping="Wrap" Foreground="#9a9996" FontSize="11"/>
</StackPanel>
</Grid>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
</Grid>
@@ -1,20 +1,22 @@
using iNKORE.UI.WPF.Helpers;
using Ink_Canvas.Helpers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace Ink_Canvas.Windows.SettingsViews
{
public partial class UpdateCenterPanel : UserControl
{
private bool isLoaded = false;
private bool _isLoaded = false;
private string _currentTab = "Update";
private List<(string version, string downloadUrl, string releaseNotes)> _historyVersions = new List<(string, string, string)>();
public UpdateCenterPanel()
{
@@ -24,17 +26,21 @@ namespace Ink_Canvas.Windows.SettingsViews
private void UpdateCenterPanel_Loaded(object sender, RoutedEventArgs e)
{
if (!isLoaded)
if (!_isLoaded)
{
isLoaded = true;
_isLoaded = true;
LoadSettings();
SwitchTab("Update");
CheckUpdateStatus();
LoadUpdateLog(MainWindow.Settings?.Startup?.UpdateChannel ?? UpdateChannel.Release);
ApplyTheme();
}
}
private void LoadSettings()
{
if (MainWindow.Settings == null) return;
try
{
var version = Assembly.GetExecutingAssembly().GetName().Version;
@@ -42,6 +48,64 @@ namespace Ink_Canvas.Windows.SettingsViews
CurrentVersionText.Text = $"当前版本: v{version} | {platform}";
LoadLastCheckTime();
var toggleSwitchIsAutoUpdate = FindToggleSwitch("ToggleSwitchIsAutoUpdate");
if (toggleSwitchIsAutoUpdate != null)
{
bool isAutoUpdate = MainWindow.Settings.Startup.IsAutoUpdate;
SetToggleSwitchState(toggleSwitchIsAutoUpdate, isAutoUpdate);
}
var toggleSwitchIsAutoUpdateWithSilence = FindToggleSwitch("ToggleSwitchIsAutoUpdateWithSilence");
if (toggleSwitchIsAutoUpdateWithSilence != null)
{
bool isAutoUpdateWithSilence = MainWindow.Settings.Startup.IsAutoUpdateWithSilence;
SetToggleSwitchState(toggleSwitchIsAutoUpdateWithSilence, isAutoUpdateWithSilence);
AutoUpdateWithSilencePanel.Visibility = MainWindow.Settings.Startup.IsAutoUpdate ? Visibility.Visible : Visibility.Collapsed;
AutoUpdateTimePeriodSeparator.Visibility = MainWindow.Settings.Startup.IsAutoUpdate ? Visibility.Visible : Visibility.Collapsed;
}
if (AutoUpdateTimePeriodBlock != null)
{
AutoUpdateTimePeriodBlock.Visibility =
(MainWindow.Settings.Startup.IsAutoUpdateWithSilence && MainWindow.Settings.Startup.IsAutoUpdate) ?
Visibility.Visible : Visibility.Collapsed;
}
if (AutoUpdateWithSilenceStartTimeComboBox != null)
{
var startTime = MainWindow.Settings.Startup.AutoUpdateWithSilenceStartTime ?? "06:00";
var startItem = AutoUpdateWithSilenceStartTimeComboBox.Items.Cast<ComboBoxItem>()
.FirstOrDefault(item => item.Tag?.ToString() == startTime.Replace(":", ""));
if (startItem != null)
{
AutoUpdateWithSilenceStartTimeComboBox.SelectedItem = startItem;
}
}
if (AutoUpdateWithSilenceEndTimeComboBox != null)
{
var endTime = MainWindow.Settings.Startup.AutoUpdateWithSilenceEndTime ?? "22:00";
var endItem = AutoUpdateWithSilenceEndTimeComboBox.Items.Cast<ComboBoxItem>()
.FirstOrDefault(item => item.Tag?.ToString() == endTime.Replace(":", ""));
if (endItem != null)
{
AutoUpdateWithSilenceEndTimeComboBox.SelectedItem = endItem;
}
}
if (MainWindow.Settings.Startup.UpdateChannel == UpdateChannel.Release)
{
UpdateUpdateChannelButtons(UpdateChannel.Release);
}
else if (MainWindow.Settings.Startup.UpdateChannel == UpdateChannel.Preview)
{
UpdateUpdateChannelButtons(UpdateChannel.Preview);
}
else
{
UpdateUpdateChannelButtons(UpdateChannel.Beta);
}
}
catch (Exception ex)
{
@@ -94,6 +158,58 @@ namespace Ink_Canvas.Windows.SettingsViews
}
}
private void Tab_Click(object sender, RoutedEventArgs e)
{
var border = sender as Border;
if (border == null) return;
string tag = border.Tag?.ToString();
if (string.IsNullOrEmpty(tag)) return;
SwitchTab(tag);
}
private void SwitchTab(string tabName)
{
_currentTab = tabName;
bool isDarkTheme = ThemeHelper.IsDarkTheme;
var selectedBrush = isDarkTheme ? new SolidColorBrush(Color.FromRgb(25, 25, 25)) : new SolidColorBrush(Color.FromRgb(225, 225, 225));
var unselectedBrush = new SolidColorBrush(Colors.Transparent);
TabUpdate.Background = tabName == "Update" ? selectedBrush : unselectedBrush;
var updateText = TabUpdate.Child as TextBlock;
if (updateText != null)
{
updateText.FontWeight = tabName == "Update" ? FontWeights.Bold : FontWeights.Normal;
updateText.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
TabRollback.Background = tabName == "Rollback" ? selectedBrush : unselectedBrush;
var rollbackText = TabRollback.Child as TextBlock;
if (rollbackText != null)
{
rollbackText.FontWeight = tabName == "Rollback" ? FontWeights.Bold : FontWeights.Normal;
rollbackText.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
TabSettings.Background = tabName == "Settings" ? selectedBrush : unselectedBrush;
var settingsText = TabSettings.Child as TextBlock;
if (settingsText != null)
{
settingsText.FontWeight = tabName == "Settings" ? FontWeights.Bold : FontWeights.Normal;
settingsText.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
UpdateTabContent.Visibility = tabName == "Update" ? Visibility.Visible : Visibility.Collapsed;
RollbackTabContent.Visibility = tabName == "Rollback" ? Visibility.Visible : Visibility.Collapsed;
SettingsTabContent.Visibility = tabName == "Settings" ? Visibility.Visible : Visibility.Collapsed;
if (tabName == "Rollback" && _historyVersions.Count == 0)
{
LoadHistoryVersions();
}
}
private void CheckUpdateButton_Click(object sender, RoutedEventArgs e)
{
CheckUpdateStatus(true);
@@ -103,15 +219,7 @@ namespace Ink_Canvas.Windows.SettingsViews
{
try
{
var mainWindow = Application.Current.MainWindow as MainWindow;
if (mainWindow != null)
{
var method = typeof(MainWindow).GetMethod("CheckForUpdates", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (method != null)
{
method.Invoke(mainWindow, null);
}
}
MainWindowSettingsHelper.InvokeMainWindowMethod("ManualUpdateButton_Click", sender, e);
}
catch (Exception ex)
{
@@ -169,6 +277,15 @@ namespace Ink_Canvas.Windows.SettingsViews
UpdateAvailablePanel.Visibility = Visibility.Collapsed;
}
if (!string.IsNullOrEmpty(releaseNotes))
{
UpdateLogViewer.Markdown = releaseNotes;
}
else
{
LoadUpdateLog(updateChannel);
}
if (manualCheck)
{
SaveLastCheckTime();
@@ -191,6 +308,311 @@ namespace Ink_Canvas.Windows.SettingsViews
});
}
private async void LoadUpdateLog(UpdateChannel channel)
{
try
{
var updateLog = await AutoUpdateHelper.GetUpdateLog(channel);
if (!string.IsNullOrEmpty(updateLog))
{
UpdateLogViewer.Markdown = updateLog;
}
else
{
UpdateLogViewer.Markdown = "暂无更新日志";
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"加载更新日志失败: {ex.Message}");
UpdateLogViewer.Markdown = "加载更新日志失败";
}
}
private async void LoadHistoryVersions()
{
try
{
HistoryLogViewer.Markdown = "正在加载历史版本...";
RollbackVersionComboBox.Items.Clear();
var updateChannel = UpdateChannel.Release;
if (MainWindow.Settings?.Startup != null)
{
updateChannel = MainWindow.Settings.Startup.UpdateChannel;
}
_historyVersions = await AutoUpdateHelper.GetAllGithubReleases(updateChannel);
if (_historyVersions.Count > 0)
{
var markdown = new System.Text.StringBuilder();
markdown.AppendLine("# 历史版本列表\n");
foreach (var (version, downloadUrl, releaseNotes) in _historyVersions)
{
markdown.AppendLine($"## {version}\n");
if (!string.IsNullOrEmpty(releaseNotes))
{
var notes = releaseNotes.Length > 200 ? releaseNotes.Substring(0, 200) + "..." : releaseNotes;
markdown.AppendLine(notes);
}
markdown.AppendLine("\n---\n");
}
HistoryLogViewer.Markdown = markdown.ToString();
foreach (var (version, downloadUrl, releaseNotes) in _historyVersions)
{
var item = new ComboBoxItem
{
Content = version,
Tag = (version, downloadUrl, releaseNotes)
};
RollbackVersionComboBox.Items.Add(item);
}
}
else
{
HistoryLogViewer.Markdown = "未获取到历史版本信息。";
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"加载历史版本失败: {ex.Message}");
HistoryLogViewer.Markdown = "加载历史版本失败";
}
}
private void RollbackVersionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (RollbackVersionComboBox.SelectedItem is ComboBoxItem selectedItem && selectedItem.Tag is (string version, string downloadUrl, string releaseNotes))
{
if (!string.IsNullOrEmpty(releaseNotes))
{
HistoryLogViewer.Markdown = $"# {version}\n\n{releaseNotes}";
}
else
{
HistoryLogViewer.Markdown = $"# {version}\n\n无更新日志";
}
}
}
private void RollbackButton_Click(object sender, RoutedEventArgs e)
{
try
{
var updateChannel = UpdateChannel.Release;
if (MainWindow.Settings?.Startup != null)
{
updateChannel = MainWindow.Settings.Startup.UpdateChannel;
}
var rollbackWindow = new HistoryRollbackWindow(updateChannel);
rollbackWindow.ShowDialog();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"打开历史版本回滚窗口失败: {ex.Message}");
}
}
private void FixVersionButton_Click(object sender, RoutedEventArgs e)
{
MainWindowSettingsHelper.InvokeMainWindowMethod("FixVersionButton_Click", sender, e);
}
private void OptionButton_Click(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
var border = sender as Border;
if (border == null) return;
string tag = border.Tag?.ToString();
if (string.IsNullOrEmpty(tag)) return;
switch (tag)
{
case "UpdateChannel_Release":
MainWindowSettingsHelper.UpdateSettingDirectly(() =>
{
MainWindow.Settings.Startup.UpdateChannel = UpdateChannel.Release;
}, "UpdateChannelSelector");
MainWindowSettingsHelper.InvokeMainWindowMethod("UpdateChannelSelector_Checked",
new System.Windows.Controls.RadioButton { Tag = "Release" }, e);
UpdateUpdateChannelButtons(UpdateChannel.Release);
LoadHistoryVersions();
LoadUpdateLog(UpdateChannel.Release);
break;
case "UpdateChannel_Preview":
MainWindowSettingsHelper.UpdateSettingDirectly(() =>
{
MainWindow.Settings.Startup.UpdateChannel = UpdateChannel.Preview;
}, "UpdateChannelSelector");
MainWindowSettingsHelper.InvokeMainWindowMethod("UpdateChannelSelector_Checked",
new System.Windows.Controls.RadioButton { Tag = "Preview" }, e);
UpdateUpdateChannelButtons(UpdateChannel.Preview);
LoadHistoryVersions();
LoadUpdateLog(UpdateChannel.Preview);
break;
case "UpdateChannel_Beta":
MainWindowSettingsHelper.UpdateSettingDirectly(() =>
{
MainWindow.Settings.Startup.UpdateChannel = UpdateChannel.Beta;
}, "UpdateChannelSelector");
MainWindowSettingsHelper.InvokeMainWindowMethod("UpdateChannelSelector_Checked",
new System.Windows.Controls.RadioButton { Tag = "Beta" }, e);
UpdateUpdateChannelButtons(UpdateChannel.Beta);
LoadHistoryVersions();
LoadUpdateLog(UpdateChannel.Beta);
break;
}
}
private void UpdateUpdateChannelButtons(UpdateChannel selectedChannel)
{
try
{
bool isDarkTheme = ThemeHelper.IsDarkTheme;
var selectedBrush = isDarkTheme ? new SolidColorBrush(Color.FromRgb(25, 25, 25)) : new SolidColorBrush(Color.FromRgb(225, 225, 225));
var unselectedBrush = new SolidColorBrush(Colors.Transparent);
if (UpdateChannelReleaseBorder != null)
{
bool isSelected = selectedChannel == UpdateChannel.Release;
UpdateChannelReleaseBorder.Background = isSelected ? selectedBrush : unselectedBrush;
var textBlock = UpdateChannelReleaseBorder.Child as TextBlock;
if (textBlock != null)
{
textBlock.FontWeight = isSelected ? FontWeights.Bold : FontWeights.Normal;
textBlock.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
}
if (UpdateChannelPreviewBorder != null)
{
bool isSelected = selectedChannel == UpdateChannel.Preview;
UpdateChannelPreviewBorder.Background = isSelected ? selectedBrush : unselectedBrush;
var textBlock = UpdateChannelPreviewBorder.Child as TextBlock;
if (textBlock != null)
{
textBlock.FontWeight = isSelected ? FontWeights.Bold : FontWeights.Normal;
textBlock.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
}
if (UpdateChannelBetaBorder != null)
{
bool isSelected = selectedChannel == UpdateChannel.Beta;
UpdateChannelBetaBorder.Background = isSelected ? selectedBrush : unselectedBrush;
var textBlock = UpdateChannelBetaBorder.Child as TextBlock;
if (textBlock != null)
{
textBlock.FontWeight = isSelected ? FontWeights.Bold : FontWeights.Normal;
textBlock.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"更新更新通道按钮状态时出错: {ex.Message}");
}
}
private void ToggleSwitch_Click(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
var border = sender as Border;
if (border == null) return;
string tag = border.Tag?.ToString();
if (string.IsNullOrEmpty(tag)) return;
bool currentState = GetCurrentSettingValue(tag);
bool newState = !currentState;
SetToggleSwitchState(border, newState);
switch (tag)
{
case "IsAutoUpdate":
MainWindowSettingsHelper.InvokeToggleSwitchToggled("ToggleSwitchIsAutoUpdate", newState);
AutoUpdateWithSilencePanel.Visibility = newState ? Visibility.Visible : Visibility.Collapsed;
AutoUpdateTimePeriodSeparator.Visibility = newState ? Visibility.Visible : Visibility.Collapsed;
if (AutoUpdateTimePeriodBlock != null)
{
AutoUpdateTimePeriodBlock.Visibility =
(MainWindow.Settings.Startup.IsAutoUpdateWithSilence && MainWindow.Settings.Startup.IsAutoUpdate) ?
Visibility.Visible : Visibility.Collapsed;
}
break;
case "IsAutoUpdateWithSilence":
MainWindowSettingsHelper.InvokeToggleSwitchToggled("ToggleSwitchIsAutoUpdateWithSilence", newState);
if (AutoUpdateTimePeriodBlock != null)
{
AutoUpdateTimePeriodBlock.Visibility = newState ? Visibility.Visible : Visibility.Collapsed;
}
break;
}
}
private bool GetCurrentSettingValue(string tag)
{
if (MainWindow.Settings == null) return false;
try
{
switch (tag)
{
case "IsAutoUpdate":
return MainWindow.Settings.Startup?.IsAutoUpdate ?? false;
case "IsAutoUpdateWithSilence":
return MainWindow.Settings.Startup?.IsAutoUpdateWithSilence ?? false;
default:
return false;
}
}
catch
{
return false;
}
}
private Border FindToggleSwitch(string name)
{
return this.FindDescendantByName(name) as Border;
}
private void SetToggleSwitchState(Border toggleSwitch, bool isOn)
{
if (toggleSwitch == null) return;
toggleSwitch.Background = isOn
? new SolidColorBrush(Color.FromRgb(53, 132, 228))
: (ThemeHelper.IsDarkTheme ? ThemeHelper.GetButtonBackgroundBrush() : new SolidColorBrush(Color.FromRgb(225, 225, 225)));
var innerBorder = toggleSwitch.Child as Border;
if (innerBorder != null)
{
innerBorder.HorizontalAlignment = isOn ? HorizontalAlignment.Right : HorizontalAlignment.Left;
innerBorder.Background = new SolidColorBrush(Colors.White);
}
}
private void AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isLoaded) return;
MainWindowSettingsHelper.InvokeComboBoxSelectionChanged("AutoUpdateWithSilenceStartTimeComboBox", AutoUpdateWithSilenceStartTimeComboBox?.SelectedItem);
}
private void AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isLoaded) return;
MainWindowSettingsHelper.InvokeComboBoxSelectionChanged("AutoUpdateWithSilenceEndTimeComboBox", AutoUpdateWithSilenceEndTimeComboBox?.SelectedItem);
}
public event EventHandler<RoutedEventArgs> IsTopBarNeedShadowEffect;
public event EventHandler<RoutedEventArgs> IsTopBarNeedNoShadowEffect;
@@ -207,57 +629,6 @@ namespace Ink_Canvas.Windows.SettingsViews
}
}
private void ScrollBar_Scroll(object sender, RoutedEventArgs e)
{
var scrollbar = (ScrollBar)sender;
var scrollviewer = scrollbar.FindAscendant<ScrollViewer>();
if (scrollviewer != null) scrollviewer.ScrollToVerticalOffset(scrollbar.Track.Value);
}
private void ScrollBarTrack_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
var border = (Border)sender;
if (border.Child is Track track)
{
track.Width = 16;
track.Margin = new Thickness(0, 0, -2, 0);
var scrollbar = track.FindAscendant<ScrollBar>();
if (scrollbar != null) scrollbar.Width = 16;
}
}
private void ScrollBarTrack_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
var border = (Border)sender;
if (border.Child is Track track)
{
track.Width = 6;
track.Margin = new Thickness(0, 0, 0, 0);
var scrollbar = track.FindAscendant<ScrollBar>();
if (scrollbar != null) scrollbar.Width = 6;
}
}
private void ScrollbarThumb_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var thumb = (System.Windows.Controls.Primitives.Thumb)sender;
var border = thumb.Template.FindName("ScrollbarThumbEx", thumb);
if (border is Border borderElement)
{
borderElement.Background = new SolidColorBrush(Color.FromRgb(95, 95, 95));
}
}
private void ScrollbarThumb_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var thumb = (System.Windows.Controls.Primitives.Thumb)sender;
var border = thumb.Template.FindName("ScrollbarThumbEx", thumb);
if (border is Border borderElement)
{
borderElement.Background = new SolidColorBrush(Color.FromRgb(195, 195, 195));
}
}
public void ApplyTheme()
{
try
@@ -276,6 +647,20 @@ namespace Ink_Canvas.Windows.SettingsViews
UpdateNowButton.Background = new SolidColorBrush(Color.FromRgb(0, 120, 212));
UpdateNowButton.Foreground = Brushes.White;
}
if (RollbackButton != null)
{
RollbackButton.Background = ThemeHelper.GetButtonBackgroundBrush();
RollbackButton.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
if (FixVersionButton != null)
{
FixVersionButton.Background = ThemeHelper.GetButtonBackgroundBrush();
FixVersionButton.Foreground = ThemeHelper.GetTextPrimaryBrush();
}
SwitchTab(_currentTab);
}
catch (Exception ex)
{
@@ -314,3 +699,4 @@ namespace Ink_Canvas.Windows.SettingsViews
}
}
}