Browse Source

init

master
root 2 months ago
commit
a05a81acc7
  1. 31
      App.axaml
  2. 92
      App.axaml.cs
  3. 22
      Configuration/AppSettings.cs
  4. 121
      Converters/StringConverters.cs
  5. 33
      Converters/TabStyleConverter.cs
  6. 58
      Extensions/ServiceCollectionExtensions.cs
  7. 173
      FixAutoStartup.ps1
  8. 370
      MainWindow.axaml
  9. 95
      MainWindow.axaml.cs
  10. 49
      MyAvaloniaApp.csproj
  11. 24
      MyAvaloniaApp.sln
  12. 46
      Program.cs
  13. 51
      Resources/Colors.axaml
  14. 103
      Resources/Strings.en.axaml
  15. 105
      Resources/Strings.zh-CN.axaml
  16. 43
      Services/ApiService.cs
  17. 42
      Services/DataService.cs
  18. 12
      Services/IApiService.cs
  19. 13
      Services/IDataService.cs
  20. 43
      Services/IResourceService.cs
  21. 90
      Services/LanguageManager.cs
  22. 128
      Services/ResourceService.cs
  23. 19
      ViewModels/AppViewModel.cs
  24. 425
      ViewModels/MainWindowViewModel.cs
  25. 82
      ViewModels/NavigationItem.cs
  26. 50
      ViewModels/Pages/DashboardPageViewModel.cs
  27. 40
      ViewModels/Pages/HelpPageViewModel.cs
  28. 145
      ViewModels/Pages/IconsPageViewModel.cs
  29. 50
      ViewModels/Pages/ReportsPageViewModel.cs
  30. 50
      ViewModels/Pages/SettingsPageViewModel.cs
  31. 45
      ViewModels/Pages/UsersPageViewModel.cs
  32. 71
      ViewModels/TabItem.cs
  33. 250
      Views/Pages/DashboardPageView.axaml
  34. 11
      Views/Pages/DashboardPageView.axaml.cs
  35. 225
      Views/Pages/HelpPageView.axaml
  36. 11
      Views/Pages/HelpPageView.axaml.cs
  37. 181
      Views/Pages/IconsPageView.axaml
  38. 21
      Views/Pages/IconsPageView.axaml.cs
  39. 417
      Views/Pages/ReportsPageView.axaml
  40. 11
      Views/Pages/ReportsPageView.axaml.cs
  41. 210
      Views/Pages/SettingsPageView.axaml
  42. 11
      Views/Pages/SettingsPageView.axaml.cs
  43. 200
      Views/Pages/UsersPageView.axaml
  44. 11
      Views/Pages/UsersPageView.axaml.cs
  45. 230
      WSL部署说明.md
  46. 18
      app.manifest
  47. 27
      appsettings.json
  48. BIN
      bin/Debug/net8.0/Avalonia.Base.dll
  49. BIN
      bin/Debug/net8.0/Avalonia.Controls.ColorPicker.dll
  50. BIN
      bin/Debug/net8.0/Avalonia.Controls.dll
  51. BIN
      bin/Debug/net8.0/Avalonia.DesignerSupport.dll
  52. BIN
      bin/Debug/net8.0/Avalonia.Desktop.dll
  53. BIN
      bin/Debug/net8.0/Avalonia.Diagnostics.dll
  54. BIN
      bin/Debug/net8.0/Avalonia.Dialogs.dll
  55. BIN
      bin/Debug/net8.0/Avalonia.Fonts.Inter.dll
  56. BIN
      bin/Debug/net8.0/Avalonia.FreeDesktop.dll
  57. BIN
      bin/Debug/net8.0/Avalonia.Markup.Xaml.dll
  58. BIN
      bin/Debug/net8.0/Avalonia.Markup.dll
  59. BIN
      bin/Debug/net8.0/Avalonia.Metal.dll
  60. BIN
      bin/Debug/net8.0/Avalonia.MicroCom.dll
  61. BIN
      bin/Debug/net8.0/Avalonia.Native.dll
  62. BIN
      bin/Debug/net8.0/Avalonia.OpenGL.dll
  63. BIN
      bin/Debug/net8.0/Avalonia.ReactiveUI.dll
  64. BIN
      bin/Debug/net8.0/Avalonia.Remote.Protocol.dll
  65. BIN
      bin/Debug/net8.0/Avalonia.Skia.dll
  66. BIN
      bin/Debug/net8.0/Avalonia.Themes.Fluent.dll
  67. BIN
      bin/Debug/net8.0/Avalonia.Themes.Simple.dll
  68. BIN
      bin/Debug/net8.0/Avalonia.Vulkan.dll
  69. BIN
      bin/Debug/net8.0/Avalonia.Win32.Automation.dll
  70. BIN
      bin/Debug/net8.0/Avalonia.Win32.dll
  71. BIN
      bin/Debug/net8.0/Avalonia.X11.dll
  72. BIN
      bin/Debug/net8.0/Avalonia.dll
  73. BIN
      bin/Debug/net8.0/DynamicData.dll
  74. BIN
      bin/Debug/net8.0/HarfBuzzSharp.dll
  75. BIN
      bin/Debug/net8.0/MicroCom.Runtime.dll
  76. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Configuration.Abstractions.dll
  77. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Configuration.Binder.dll
  78. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Configuration.CommandLine.dll
  79. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Configuration.EnvironmentVariables.dll
  80. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Configuration.FileExtensions.dll
  81. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Configuration.Json.dll
  82. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Configuration.UserSecrets.dll
  83. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Configuration.dll
  84. BIN
      bin/Debug/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll
  85. BIN
      bin/Debug/net8.0/Microsoft.Extensions.DependencyInjection.dll
  86. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Diagnostics.Abstractions.dll
  87. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Diagnostics.dll
  88. BIN
      bin/Debug/net8.0/Microsoft.Extensions.FileProviders.Abstractions.dll
  89. BIN
      bin/Debug/net8.0/Microsoft.Extensions.FileProviders.Physical.dll
  90. BIN
      bin/Debug/net8.0/Microsoft.Extensions.FileSystemGlobbing.dll
  91. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Hosting.Abstractions.dll
  92. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Hosting.dll
  93. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Logging.Abstractions.dll
  94. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Logging.Configuration.dll
  95. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Logging.Console.dll
  96. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Logging.Debug.dll
  97. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Logging.EventLog.dll
  98. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Logging.EventSource.dll
  99. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Logging.dll
  100. BIN
      bin/Debug/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll

31
App.axaml

@ -0,0 +1,31 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyAvaloniaApp.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="Resources/Colors.axaml"/>
<!-- 根据系统语言选择资源文件,默认使用中文 -->
<ResourceInclude Source="Resources/Strings.zh-CN.axaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
<Application.Styles>
<FluentTheme />
<!-- Linux字体回退配置 -->
<Style Selector="TextBlock">
<Setter Property="FontFamily" Value="Inter, DejaVu Sans, Liberation Sans, Arial, sans-serif" />
</Style>
<Style Selector="Button">
<Setter Property="FontFamily" Value="Inter, DejaVu Sans, Liberation Sans, Arial, sans-serif" />
</Style>
<Style Selector="Label">
<Setter Property="FontFamily" Value="Inter, DejaVu Sans, Liberation Sans, Arial, sans-serif" />
</Style>
</Application.Styles>
</Application>

92
App.axaml.cs

@ -0,0 +1,92 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MyAvaloniaApp.Configuration;
using MyAvaloniaApp.Extensions;
using ReactiveUI;
using System;
using System.IO;
namespace MyAvaloniaApp;
public partial class App : Application
{
private IServiceProvider? _serviceProvider;
private ILogger<App>? _logger;
/// <summary>
/// 无参构造函数,用于 Avalonia 框架初始化
/// </summary>
public App()
{
}
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
// 在框架初始化完成后创建和配置 HostBuilder
var host = CreateHostBuilder().Build();
_serviceProvider = host.Services;
_logger = _serviceProvider.GetRequiredService<ILogger<App>>();
_logger.LogInformation("App 框架初始化完成,HostBuilder 已创建并配置");
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
_logger.LogInformation("使用依赖注入创建 MainWindow");
desktop.MainWindow = _serviceProvider.GetRequiredService<MainWindow>();
}
base.OnFrameworkInitializationCompleted();
_logger.LogInformation("框架初始化完成");
}
/// <summary>
/// 创建 HostBuilder
/// </summary>
/// <returns>HostBuilder</returns>
private IHostBuilder CreateHostBuilder() =>
Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((context, config) =>
{
// 配置应用程序设置
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
})
.ConfigureLogging((context, logging) =>
{
// 配置日志
logging.ClearProviders();
logging.AddConfiguration(context.Configuration.GetSection("Logging"));
// 移除控制台日志,只保留调试输出
// logging.AddConsole();
logging.AddDebug();
})
.ConfigureServices((context, services) =>
{
// 注册配置
services.Configure<AppSettings>(context.Configuration.GetSection("AppSettings"));
// 注册业务服务
services.AddBusinessServices();
// 注册 ViewModel
services.AddViewModels();
// 注册 ReactiveUI 服务
services.AddReactiveUI();
// 注册 Avalonia 应用程序
services.AddTransient<MainWindow>();
});
}

22
Configuration/AppSettings.cs

@ -0,0 +1,22 @@
namespace MyAvaloniaApp.Configuration;
/// <summary>
/// 应用程序设置
/// </summary>
public class AppSettings
{
public string ApplicationName { get; set; } = "My Avalonia App";
public string Version { get; set; } = "1.0.0";
public string Environment { get; set; } = "Development";
public FeatureSettings Features { get; set; } = new();
}
/// <summary>
/// 功能设置
/// </summary>
public class FeatureSettings
{
public bool EnableLogging { get; set; } = true;
public bool EnableMetrics { get; set; } = false;
public bool EnableTelemetry { get; set; } = false;
}

121
Converters/StringConverters.cs

@ -0,0 +1,121 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
using HeroIconsAvalonia.Enums;
using System;
using System.Globalization;
namespace MyAvaloniaApp.Converters;
/// <summary>
/// 字符串转换器类
/// </summary>
public static class StringConverters
{
/// <summary>
/// 角色到颜色的转换器
/// </summary>
public static readonly IValueConverter RoleToColorConverter = new RoleToColorConverter();
/// <summary>
/// 状态到颜色的转换器
/// </summary>
public static readonly IValueConverter StatusToColorConverter = new StatusToColorConverter();
/// <summary>
/// 空值到布尔值的转换器
/// </summary>
public static readonly IValueConverter NullToBoolConverter = new NullToBoolConverter();
/// <summary>
/// 布尔值到图标类型的转换器
/// </summary>
public static readonly IValueConverter BoolToIconConverter = new BoolToIconConverter();
}
/// <summary>
/// 角色到颜色转换器
/// </summary>
public class RoleToColorConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string role)
{
return role switch
{
"管理员" => new SolidColorBrush(Color.FromRgb(220, 53, 69)), // 红色
"编辑" => new SolidColorBrush(Color.FromRgb(255, 193, 7)), // 黄色
"用户" => new SolidColorBrush(Color.FromRgb(40, 167, 69)), // 绿色
_ => new SolidColorBrush(Color.FromRgb(108, 117, 125)) // 灰色
};
}
return new SolidColorBrush(Color.FromRgb(108, 117, 125));
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 状态到颜色转换器
/// </summary>
public class StatusToColorConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string status)
{
return status switch
{
"在线" => new SolidColorBrush(Color.FromRgb(40, 167, 69)), // 绿色
"离线" => new SolidColorBrush(Color.FromRgb(108, 117, 125)), // 灰色
"忙碌" => new SolidColorBrush(Color.FromRgb(220, 53, 69)), // 红色
_ => new SolidColorBrush(Color.FromRgb(108, 117, 125)) // 灰色
};
}
return new SolidColorBrush(Color.FromRgb(108, 117, 125));
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 空值到布尔值转换器
/// </summary>
public class NullToBoolConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return value != null;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 布尔值到图标类型转换器
/// </summary>
public class BoolToIconConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is bool isExpanded)
{
return isExpanded ? IconType.ChevronDown : IconType.ChevronRight;
}
return IconType.ChevronRight;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

33
Converters/TabStyleConverter.cs

@ -0,0 +1,33 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
using System;
using System.Globalization;
namespace MyAvaloniaApp.Converters;
/// <summary>
/// 标签页样式转换器
/// </summary>
public class TabStyleConverter : IValueConverter
{
public static readonly TabStyleConverter Instance = new();
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is bool isSelected && parameter is string styleType)
{
return styleType switch
{
"Background" => isSelected ? new SolidColorBrush(Color.FromRgb(227, 242, 253)) : new SolidColorBrush(Colors.White),
"BorderBrush" => isSelected ? new SolidColorBrush(Color.FromRgb(33, 150, 243)) : new SolidColorBrush(Color.FromRgb(208, 208, 208)),
"Foreground" => isSelected ? new SolidColorBrush(Color.FromRgb(33, 150, 243)) : new SolidColorBrush(Colors.Black),
_ => new SolidColorBrush(Colors.White)
};
}
return new SolidColorBrush(Colors.White);
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

58
Extensions/ServiceCollectionExtensions.cs

@ -0,0 +1,58 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MyAvaloniaApp.Services;
using MyAvaloniaApp.ViewModels;
using ReactiveUI;
using Splat;
using System;
namespace MyAvaloniaApp.Extensions;
/// <summary>
/// 服务集合扩展方法
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// 添加 ReactiveUI 相关服务
/// </summary>
/// <param name="services">服务集合</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddReactiveUI(this IServiceCollection services)
{
// 注册 ReactiveUI 相关服务
services.AddSingleton<IScreen, AppViewModel>();
return services;
}
/// <summary>
/// 添加业务服务
/// </summary>
/// <param name="services">服务集合</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddBusinessServices(this IServiceCollection services)
{
// 注册业务服务
services.AddTransient<IDataService, DataService>();
services.AddTransient<IApiService, ApiService>();
// 注册资源服务
services.AddSingleton<IResourceService, ResourceService>();
return services;
}
/// <summary>
/// 添加 ViewModel 服务
/// </summary>
/// <param name="services">服务集合</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddViewModels(this IServiceCollection services)
{
// 注册 ViewModel
services.AddTransient<MainWindowViewModel>();
return services;
}
}

173
FixAutoStartup.ps1

@ -0,0 +1,173 @@
# ============================================
# WSL Superset 自启动修复脚本
# 功能:修复 WSL-Superset 自启动问题,重新配置任务计划程序
# 创建时间:2025年1月10日
# 版本:1.0 - 修复自启动问题
# ============================================
# 设置控制台编码为 UTF-8 以支持中文显示
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
# 日志记录函数
function Write-Log {
param(
[string]$Message,
[string]$Level = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "[$timestamp] [$Level] $Message"
Write-Host $logMessage
}
# 检查是否以管理员权限运行
function Test-Administrator {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
# 主函数
function Fix-AutoStartup {
try {
Write-Log "Starting WSL-Superset auto-startup fix process"
# 检查管理员权限
if (-not (Test-Administrator)) {
Write-Log "ERROR: This script requires administrator privileges" "ERROR"
Write-Log "Please run PowerShell as Administrator and try again" "ERROR"
return 1
}
# 获取当前脚本目录
$scriptDir = if ($MyInvocation.MyCommand.Path) {
Split-Path -Parent $MyInvocation.MyCommand.Path
} else {
Get-Location
}
$batFilePath = Join-Path $scriptDir "startup-superset.bat"
# 检查批处理文件是否存在
if (-not (Test-Path $batFilePath)) {
Write-Log "ERROR: startup-superset.bat not found in current directory" "ERROR"
Write-Log "Expected path: $batFilePath" "ERROR"
return 1
}
Write-Log "Found batch file: $batFilePath"
# 任务配置参数
$taskName = "WSL-Superset-AutoStart"
$taskDescription = "Auto restart Superset Docker container via WSL on system startup (Fixed version)"
$taskPath = "\WSL-Containers\"
Write-Log "Task Name: $taskName"
Write-Log "Task Description: $taskDescription"
Write-Log "Task Path: $taskPath"
# 删除现有任务(如果存在)
Write-Log "Removing existing task if present"
try {
$existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
if ($existingTask) {
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
Write-Log "Existing task removed successfully"
} else {
Write-Log "No existing task found"
}
} catch {
Write-Log "WARNING: Error removing existing task: $($_.Exception.Message)" "WARN"
}
# 创建任务操作
Write-Log "Creating task action"
$action = New-ScheduledTaskAction -Execute $batFilePath -WorkingDirectory $scriptDir
# 创建触发器(用户登录后,增加延迟)
Write-Log "Creating logon trigger with 3-minute delay"
$trigger = New-ScheduledTaskTrigger -AtLogOn
$trigger.Delay = "PT3M" # 用户登录后延迟3分钟启动
# 创建任务设置(增强错误处理)
Write-Log "Creating task settings with enhanced error handling"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -ExecutionTimeLimit (New-TimeSpan -Minutes 10) -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 5)
# 创建任务主体(以当前用户身份运行)
Write-Log "Creating task principal with current user account"
$principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive -RunLevel Highest
# 注册任务
Write-Log "Registering scheduled task with enhanced configuration"
try {
$null = Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Description $taskDescription -TaskPath $taskPath
Write-Log "Task registration completed successfully"
} catch {
Write-Log "ERROR: Failed to register scheduled task" "ERROR"
Write-Log "Exception: $($_.Exception.Message)" "ERROR"
return 1
}
# 验证任务创建
Write-Log "Verifying task creation"
$taskExists = $false
try {
$null = Get-ScheduledTask -TaskName $taskName -ErrorAction Stop
$taskExists = $true
} catch {
$taskExists = $false
}
if ($taskExists) {
Write-Log "SUCCESS: Task created successfully with enhanced configuration" "SUCCESS"
Write-Log "Task Name: $taskName"
Write-Log "Task Path: $taskPath"
Write-Log "Trigger: User Logon with 3-minute delay"
Write-Log "Execution Time Limit: 10 minutes"
Write-Log "Restart Count: 3 attempts"
Write-Log "Restart Interval: 5 minutes"
Write-Log "Auto-startup fix completed successfully" "SUCCESS"
Write-Log "The startup-superset.bat will now run automatically after user logon with enhanced error handling"
return 0
} else {
Write-Log "ERROR: Failed to create scheduled task" "ERROR"
return 1
}
} catch {
Write-Log "ERROR: An exception occurred during fix process" "ERROR"
Write-Log "Exception: $($_.Exception.Message)" "ERROR"
Write-Log "Stack Trace: $($_.ScriptStackTrace)" "ERROR"
return 1
}
}
# 执行主函数
Write-Log "=== WSL Superset Auto-Startup Fix ==="
Write-Log "This script will fix the WSL-Superset auto-startup issues"
Write-Log ""
$result = Fix-AutoStartup
if ($result -eq 0) {
Write-Log ""
Write-Log "=== Fix Completed Successfully ===" "SUCCESS"
Write-Log "Your WSL-Superset auto-startup has been fixed with the following improvements:"
Write-Log "- User logon trigger with 3-minute delay to ensure WSL is ready"
Write-Log "- Enhanced error handling with retry mechanisms"
Write-Log "- 10-minute execution time limit"
Write-Log "- 3 restart attempts with 5-minute intervals"
Write-Log "- Improved logging and error reporting"
Write-Log ""
Write-Log "The task will now run automatically after user logon"
Write-Log "You can view the task in Task Scheduler under: WSL-Containers\WSL-Superset-AutoStart"
} else {
Write-Log ""
Write-Log "=== Fix Failed ===" "ERROR"
Write-Log "Please check the error messages above and try again"
}
Write-Log ""
Write-Log "Press any key to exit..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

370
MainWindow.axaml

@ -0,0 +1,370 @@
<Window xmlns="https://github.com/avaloniaui"
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:vm="using:MyAvaloniaApp.ViewModels"
xmlns:converters="using:MyAvaloniaApp.Converters"
xmlns:tooltip="using:Avalonia.Controls"
xmlns:heroicons="clr-namespace:HeroIconsAvalonia.Controls;assembly=HeroIconsAvalonia"
mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="800"
x:Class="MyAvaloniaApp.MainWindow"
x:DataType="vm:MainWindowViewModel"
Title="{Binding Title}"
MinWidth="1000" MinHeight="600"
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="None">
<Design.DataContext>
<vm:MainWindowViewModel />
</Design.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" MinWidth="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧导航栏 -->
<Border Grid.Column="0"
Background="{StaticResource PrimaryDark}"
BorderBrush="{StaticResource PrimaryDarkHover}"
BorderThickness="0,0,1,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 导航栏标题 -->
<StackPanel Grid.Row="0" Margin="20,20,20,30">
<TextBlock Text="{StaticResource AppTitle}"
FontSize="20"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="{StaticResource AppSubtitle}"
FontSize="12"
Foreground="{StaticResource SecondaryGray}"
HorizontalAlignment="Center"
Margin="0,5,0,0"/>
</StackPanel>
<!-- 导航菜单 -->
<ScrollViewer Grid.Row="1"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Margin="10,0,10,0">
<ItemsControl ItemsSource="{Binding NavigationItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<!-- 主导航项 -->
<Button Command="{Binding $parent[Window].DataContext.NavigateCommand}"
CommandParameter="{Binding}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
Margin="0,2"
Padding="15,12"
FontSize="14"
Background="Transparent"
Foreground="White"
BorderThickness="0"
CornerRadius="8">
<Button.Styles>
<Style Selector="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{StaticResource PrimaryDarkHover}"/>
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/>
</Style>
<Style Selector="Button:selected">
<Setter Property="Background" Value="{StaticResource PrimaryBlue}"/>
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/>
</Style>
</Button.Styles>
<Button.Content>
<StackPanel Orientation="Horizontal" Spacing="10">
<heroicons:HeroIcon Type="{Binding IconType}"
Width="16" Height="16"
Foreground="{StaticResource TextWhite}"/>
<TextBlock Text="{Binding Title}"
VerticalAlignment="Center"/>
</StackPanel>
</Button.Content>
</Button>
<!-- 子导航项 -->
<ItemsControl ItemsSource="{Binding Children}"
IsVisible="{Binding IsExpanded}"
Margin="20,0,0,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding $parent[Window].DataContext.NavigateCommand}"
CommandParameter="{Binding}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
Margin="0,1"
Padding="15,10"
FontSize="13"
Background="Transparent"
Foreground="{StaticResource SecondaryGray}"
BorderThickness="0"
CornerRadius="6">
<Button.Styles>
<Style Selector="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{StaticResource SecondaryGray}"/>
</Style>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{StaticResource PrimaryDarkHover}"/>
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/>
</Style>
<Style Selector="Button:selected">
<Setter Property="Background" Value="{StaticResource PrimaryBlue}"/>
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/>
</Style>
</Button.Styles>
<Button.Content>
<StackPanel Orientation="Horizontal" Spacing="8">
<heroicons:HeroIcon Type="{Binding IconType}"
Width="14" Height="14"
Foreground="{Binding $parent[Button].Foreground}"/>
<TextBlock Text="{Binding Title}"
VerticalAlignment="Center"/>
</StackPanel>
</Button.Content>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<!-- 底部信息 -->
<StackPanel Grid.Row="2" Margin="20,0,20,20">
<Border Background="{StaticResource PrimaryDarkHover}" CornerRadius="8" Padding="15">
<StackPanel>
<TextBlock Text="{StaticResource VersionInfo}"
FontSize="12"
Foreground="{StaticResource SecondaryGray}"
HorizontalAlignment="Center"/>
<TextBlock Text="{StaticResource VersionNumber}"
FontSize="14"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"
Margin="0,5,0,0"/>
</StackPanel>
</Border>
</StackPanel>
</Grid>
</Border>
<!-- 右侧主内容区域 -->
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 头部区域 -->
<Border Grid.Row="0"
Background="{StaticResource BackgroundWhite}"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="0,0,0,1"
Padding="0,0,0,0">
<Grid Height="50" Name="TitleBarGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- 左侧标题区域 -->
<StackPanel Grid.Column="0"
VerticalAlignment="Center"
Margin="20,0,0,0">
<TextBlock Text="{Binding HeaderTitle}"
FontSize="18"
FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"/>
<TextBlock Text="{Binding HeaderSubtitle}"
FontSize="12"
Foreground="{StaticResource SecondaryGrayDark}"
Margin="0,2,0,0"/>
</StackPanel>
<!-- 右侧按钮区域 -->
<StackPanel Grid.Column="1"
Orientation="Horizontal"
VerticalAlignment="Center"
Margin="0,0,0,0">
<!-- 窗口控制按钮组 -->
<StackPanel Orientation="Horizontal" Spacing="0">
<!-- 最小化按钮 -->
<Button Name="MinimizeButton"
Width="46" Height="30"
Background="Transparent"
BorderThickness="0"
tooltip:ToolTip.Tip="{StaticResource BtnMinimize}">
<Button.Styles>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{StaticResource BackgroundLight}"/>
</Style>
</Button.Styles>
<heroicons:HeroIcon Type="Minus"
Width="16" Height="16"
Foreground="{StaticResource SecondaryGrayStroke}"/>
</Button>
<!-- 最大化/还原按钮 -->
<Button Name="MaximizeButton"
Width="46" Height="30"
Background="Transparent"
BorderThickness="0"
tooltip:ToolTip.Tip="{StaticResource BtnMaximize}">
<Button.Styles>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{StaticResource BackgroundLight}"/>
</Style>
</Button.Styles>
<heroicons:HeroIcon Type="ArrowsPointingOut"
Width="16" Height="16"
Foreground="{StaticResource SecondaryGrayStroke}"/>
</Button>
<!-- 关闭按钮 -->
<Button Name="CloseButton"
Width="46" Height="30"
Background="Transparent"
BorderThickness="0"
tooltip:ToolTip.Tip="{StaticResource BtnClose}">
<Button.Styles>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{StaticResource ButtonClose}"/>
</Style>
</Button.Styles>
<heroicons:HeroIcon Type="XMark"
Width="16" Height="16"
Foreground="{StaticResource SecondaryGrayStroke}"/>
</Button>
</StackPanel>
</StackPanel>
</Grid>
</Border>
<!-- 标签页区域 -->
<Border Grid.Row="1"
Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="0,0,0,1"
Padding="0,0,0,0">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled">
<ItemsControl ItemsSource="{Binding Tabs}"
Margin="8,4,8,0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="0"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Background="{Binding IsSelected, Converter={x:Static converters:TabStyleConverter.Instance}, ConverterParameter=Background}"
BorderBrush="{Binding IsSelected, Converter={x:Static converters:TabStyleConverter.Instance}, ConverterParameter=BorderBrush}"
BorderThickness="1,1,1,0"
CornerRadius="4,4,0,0"
Margin="0,0,1,0"
Padding="12,8,8,8"
MinWidth="120"
Cursor="Hand"
Command="{Binding $parent[Window].DataContext.SelectTabCommand}"
CommandParameter="{Binding}">
<Button.Styles>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{StaticResource BackgroundLight}"/>
</Style>
</Button.Styles>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Orientation="Horizontal"
Spacing="6"
VerticalAlignment="Center">
<heroicons:HeroIcon Type="{Binding IconType}"
Width="14" Height="14"
VerticalAlignment="Center"/>
<TextBlock Text="{Binding Title}"
FontSize="13"
FontWeight="Normal"
Foreground="{Binding IsSelected, Converter={x:Static converters:TabStyleConverter.Instance}, ConverterParameter=Foreground}"
VerticalAlignment="Center"/>
</StackPanel>
<Button Grid.Column="1"
Command="{Binding $parent[Window].DataContext.CloseTabCommand}"
CommandParameter="{Binding $parent[Button].DataContext}"
Width="18" Height="18"
Background="Transparent"
Foreground="{StaticResource SecondaryGrayLight}"
BorderThickness="0"
FontSize="12"
IsVisible="{Binding CanClose}"
Margin="6,0,0,0"
CornerRadius="9"
tooltip:ToolTip.Tip="{StaticResource BtnCloseTab}">
<heroicons:HeroIcon Type="XMark"
Width="6" Height="6"
Foreground="{Binding $parent[Button].Foreground}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<Button.Styles>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{StaticResource ButtonCloseHover}"/>
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/>
</Style>
<Style Selector="Button:pressed">
<Setter Property="Background" Value="{StaticResource ButtonCloseActive}"/>
<Setter Property="Foreground" Value="{StaticResource TextWhite}"/>
</Style>
</Button.Styles>
</Button>
</Grid>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Border>
<!-- 内容区域 -->
<Border Grid.Row="2"
Background="{StaticResource BackgroundWhite}"
CornerRadius="8"
Margin="10"
Padding="5"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1">
<Border.Effect>
<DropShadowEffect Color="{StaticResource ShadowBlack}"
Opacity="0.08"
BlurRadius="12"
OffsetX="0"
OffsetY="2"/>
</Border.Effect>
<ContentPresenter Content="{Binding SelectedTab.Content}"/>
</Border>
</Grid>
</Grid>
</Window>

95
MainWindow.axaml.cs

@ -0,0 +1,95 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Controls.Primitives;
using Microsoft.Extensions.Logging;
using MyAvaloniaApp.ViewModels;
using System;
using Avalonia.Input;
namespace MyAvaloniaApp;
public partial class MainWindow : Window
{
private readonly ILogger<MainWindow>? _logger;
/// <summary>
/// 无参构造函数,用于 XAML 设计器
/// </summary>
public MainWindow()
{
InitializeComponent();
SetupWindowControls();
}
/// <summary>
/// 构造函数,接受依赖注入的 ViewModel
/// </summary>
/// <param name="viewModel">主窗口的 ViewModel</param>
/// <param name="logger">日志记录器</param>
public MainWindow(MainWindowViewModel viewModel, ILogger<MainWindow>? logger = null)
{
_logger = logger;
InitializeComponent();
DataContext = viewModel;
SetupWindowControls();
_logger?.LogInformation("MainWindow 已创建,ViewModel 已设置");
}
/// <summary>
/// 设置窗口控制按钮事件
/// </summary>
private void SetupWindowControls()
{
// 设置标题栏拖动功能
var titleBarGrid = this.FindControl<Grid>("TitleBarGrid");
if (titleBarGrid != null)
{
titleBarGrid.PointerPressed += OnTitleBarPointerPressed;
}
// 最小化按钮
var minimizeButton = this.FindControl<Button>("MinimizeButton");
if (minimizeButton != null)
{
minimizeButton.Click += (sender, e) => WindowState = WindowState.Minimized;
}
// 最大化/还原按钮
var maximizeButton = this.FindControl<Button>("MaximizeButton");
if (maximizeButton != null)
{
maximizeButton.Click += (sender, e) =>
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
ToolTip.SetTip(maximizeButton, "最大化");
}
else
{
WindowState = WindowState.Maximized;
ToolTip.SetTip(maximizeButton, "还原");
}
};
}
// 关闭按钮
var closeButton = this.FindControl<Button>("CloseButton");
if (closeButton != null)
{
closeButton.Click += (sender, e) => Close();
}
}
/// <summary>
/// 处理标题栏鼠标按下事件,实现窗口拖动
/// </summary>
private void OnTitleBarPointerPressed(object? sender, PointerPressedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
{
BeginMoveDrag(e);
}
}
}

49
MyAvaloniaApp.csproj

@ -0,0 +1,49 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<UseWPF>false</UseWPF>
<UseWindowsForms>false</UseWindowsForms>
</PropertyGroup>
<!-- Linux发布配置 -->
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64'">
<OutputType>Exe</OutputType>
<ApplicationManifest></ApplicationManifest>
<BuiltInComInteropSupport>false</BuiltInComInteropSupport>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.7" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.7" />
<PackageReference Include="Avalonia.ReactiveUI" Version="11.3.7" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.6" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.6" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.6">
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="HeroIcons.Avalonia" Version="1.0.4" />
<!-- HostBuilder 相关包 -->
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

24
MyAvaloniaApp.sln

@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyAvaloniaApp", "MyAvaloniaApp.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {12345678-1234-5678-9ABC-DEF123456789}
EndGlobalSection
EndGlobal

46
Program.cs

@ -0,0 +1,46 @@
using Avalonia;
using Avalonia.Media;
using Avalonia.ReactiveUI;
using System;
using System.Runtime.InteropServices;
namespace MyAvaloniaApp;
class Program
{
[STAThread]
public static void Main(string[] args)
{
// 简化的启动方式,HostBuilder 配置已集成到 App 中
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
/// <summary>
/// 构建 Avalonia 应用程序
/// </summary>
/// <returns>AppBuilder</returns>
public static AppBuilder BuildAvaloniaApp()
{
var builder = AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
// Linux字体配置
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
// 在Linux上使用系统字体而不是Inter字体
builder = builder.With(new FontManagerOptions
{
DefaultFamilyName = "DejaVu Sans, Liberation Sans, Arial, sans-serif"
});
}
else
{
// Windows和macOS使用Inter字体
builder = builder.WithInterFont();
}
return builder;
}
}

51
Resources/Colors.axaml

@ -0,0 +1,51 @@
<!-- 颜色资源定义文件 -->
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- 主色调 - 深色系 -->
<Color x:Key="PrimaryDark">#2C3E50</Color>
<Color x:Key="PrimaryDarkHover">#34495E</Color>
<Color x:Key="PrimaryBlue">#3498DB</Color>
<Color x:Key="PrimaryBlueHover">#2980B9</Color>
<!-- 辅助色调 - 灰色系 -->
<Color x:Key="SecondaryGray">#BDC3C7</Color>
<Color x:Key="SecondaryGrayDark">#7F8C8D</Color>
<Color x:Key="SecondaryGrayLight">#999999</Color>
<Color x:Key="SecondaryGrayStroke">#666666</Color>
<!-- 背景色系 -->
<Color x:Key="BackgroundWhite">#FFFFFF</Color>
<Color x:Key="BackgroundLight">#F5F5F5</Color>
<Color x:Key="BackgroundLightHover">#F8F9FA</Color>
<Color x:Key="BackgroundLightActive">#E9ECEF</Color>
<!-- 边框色系 -->
<Color x:Key="BorderLight">#E0E0E0</Color>
<Color x:Key="BorderMedium">#E9ECEF</Color>
<!-- 文字色系 -->
<Color x:Key="TextPrimary">#2C3E50</Color>
<Color x:Key="TextSecondary">#6C757D</Color>
<Color x:Key="TextSecondaryDark">#495057</Color>
<Color x:Key="TextWhite">#FFFFFF</Color>
<!-- 状态色系 -->
<Color x:Key="StatusSuccess">#28A745</Color>
<Color x:Key="StatusWarning">#FFC107</Color>
<Color x:Key="StatusError">#DC3545</Color>
<Color x:Key="StatusInfo">#17A2B8</Color>
<!-- 按钮色系 -->
<Color x:Key="ButtonClose">#E81123</Color>
<Color x:Key="ButtonCloseHover">#FF4444</Color>
<Color x:Key="ButtonCloseActive">#E53E3E</Color>
<!-- 阴影色系 -->
<Color x:Key="ShadowBlack">#000000</Color>
<!-- 渐变色系 -->
<Color x:Key="GradientStart">#2C3E50</Color>
<Color x:Key="GradientEnd">#34495E</Color>
</ResourceDictionary>

103
Resources/Strings.en.axaml

@ -0,0 +1,103 @@
<!-- 英文资源文件 -->
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- 应用程序标题 -->
<x:String x:Key="AppTitle">Management System</x:String>
<x:String x:Key="AppSubtitle">Management System</x:String>
<!-- 导航菜单 -->
<x:String x:Key="NavDashboard">Dashboard</x:String>
<x:String x:Key="NavUsers">User Management</x:String>
<x:String x:Key="NavSettings">System Settings</x:String>
<x:String x:Key="NavReports">Reports</x:String>
<x:String x:Key="NavHelp">Help Center</x:String>
<!-- 头部区域 -->
<x:String x:Key="HeaderTitle">Dashboard</x:String>
<x:String x:Key="HeaderSubtitle">System Overview</x:String>
<!-- 按钮文本 -->
<x:String x:Key="BtnRefresh">Refresh</x:String>
<x:String x:Key="BtnSettings">Settings</x:String>
<x:String x:Key="BtnMinimize">Minimize</x:String>
<x:String x:Key="BtnMaximize">Maximize</x:String>
<x:String x:Key="BtnRestore">Restore</x:String>
<x:String x:Key="BtnClose">Close</x:String>
<x:String x:Key="BtnCloseTab">Close Tab</x:String>
<!-- 版本信息 -->
<x:String x:Key="VersionInfo">Version Information</x:String>
<x:String x:Key="VersionNumber">v1.0.0</x:String>
<!-- 页面标题 -->
<x:String x:Key="PageDashboard">Dashboard</x:String>
<x:String x:Key="PageUsers">User Management</x:String>
<x:String x:Key="PageSettings">System Settings</x:String>
<x:String x:Key="PageReports">Reports</x:String>
<x:String x:Key="PageHelp">Help Center</x:String>
<!-- 通用文本 -->
<x:String x:Key="Loading">Loading...</x:String>
<x:String x:Key="Error">Error</x:String>
<x:String x:Key="Success">Success</x:String>
<x:String x:Key="Warning">Warning</x:String>
<x:String x:Key="Info">Information</x:String>
<x:String x:Key="Confirm">Confirm</x:String>
<x:String x:Key="Cancel">Cancel</x:String>
<x:String x:Key="Save">Save</x:String>
<x:String x:Key="Delete">Delete</x:String>
<x:String x:Key="Edit">Edit</x:String>
<x:String x:Key="Add">Add</x:String>
<x:String x:Key="Search">Search</x:String>
<x:String x:Key="Filter">Filter</x:String>
<x:String x:Key="Export">Export</x:String>
<x:String x:Key="Import">Import</x:String>
<!-- 状态文本 -->
<x:String x:Key="StatusActive">Active</x:String>
<x:String x:Key="StatusInactive">Inactive</x:String>
<x:String x:Key="StatusPending">Pending</x:String>
<x:String x:Key="StatusCompleted">Completed</x:String>
<x:String x:Key="StatusFailed">Failed</x:String>
<!-- 用户管理相关 -->
<x:String x:Key="UserList">User List</x:String>
<x:String x:Key="UserName">User Name</x:String>
<x:String x:Key="UserEmail">Email</x:String>
<x:String x:Key="UserRole">Role</x:String>
<x:String x:Key="UserStatus">Status</x:String>
<x:String x:Key="UserCreateTime">Create Time</x:String>
<x:String x:Key="UserLastLogin">Last Login</x:String>
<!-- 设置页面相关 -->
<x:String x:Key="SettingsGeneral">General Settings</x:String>
<x:String x:Key="SettingsAppearance">Appearance</x:String>
<x:String x:Key="SettingsNotifications">Notifications</x:String>
<x:String x:Key="SettingsPerformance">Performance</x:String>
<x:String x:Key="SettingsLanguage">Language</x:String>
<x:String x:Key="SettingsTheme">Theme</x:String>
<!-- 仪表板相关 -->
<x:String x:Key="DashboardOverview">Overview</x:String>
<x:String x:Key="DashboardStats">Statistics</x:String>
<x:String x:Key="DashboardCharts">Charts</x:String>
<x:String x:Key="DashboardRecent">Recent Activities</x:String>
<x:String x:Key="DashboardQuickActions">Quick Actions</x:String>
<!-- 报表相关 -->
<x:String x:Key="ReportGenerate">Generate Report</x:String>
<x:String x:Key="ReportExport">Export Report</x:String>
<x:String x:Key="ReportDateRange">Date Range</x:String>
<x:String x:Key="ReportType">Report Type</x:String>
<x:String x:Key="ReportFormat">Format</x:String>
<!-- 帮助相关 -->
<x:String x:Key="HelpDocumentation">Documentation</x:String>
<x:String x:Key="HelpFAQ">FAQ</x:String>
<x:String x:Key="HelpContact">Contact Support</x:String>
<x:String x:Key="HelpAbout">About</x:String>
<x:String x:Key="HelpVersion">Version</x:String>
<x:String x:Key="HelpCopyright">Copyright</x:String>
</ResourceDictionary>

105
Resources/Strings.zh-CN.axaml

@ -0,0 +1,105 @@
<!-- 中文资源文件 -->
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- 应用程序标题 -->
<x:String x:Key="AppTitle">系统管理</x:String>
<x:String x:Key="AppSubtitle">Management System</x:String>
<!-- 导航菜单 -->
<x:String x:Key="NavDashboard">仪表板</x:String>
<x:String x:Key="NavUsers">用户管理</x:String>
<x:String x:Key="NavSettings">系统设置</x:String>
<x:String x:Key="NavReports">报表统计</x:String>
<x:String x:Key="NavHelp">帮助中心</x:String>
<x:String x:Key="NavIcons">图标库</x:String>
<!-- 头部区域 -->
<x:String x:Key="HeaderTitle">仪表板</x:String>
<x:String x:Key="HeaderSubtitle">系统概览</x:String>
<!-- 按钮文本 -->
<x:String x:Key="BtnRefresh">刷新</x:String>
<x:String x:Key="BtnSettings">设置</x:String>
<x:String x:Key="BtnMinimize">最小化</x:String>
<x:String x:Key="BtnMaximize">最大化</x:String>
<x:String x:Key="BtnRestore">还原</x:String>
<x:String x:Key="BtnClose">关闭</x:String>
<x:String x:Key="BtnCloseTab">关闭标签页</x:String>
<!-- 版本信息 -->
<x:String x:Key="VersionInfo">版本信息</x:String>
<x:String x:Key="VersionNumber">v1.0.0</x:String>
<!-- 页面标题 -->
<x:String x:Key="PageDashboard">仪表板</x:String>
<x:String x:Key="PageUsers">用户管理</x:String>
<x:String x:Key="PageSettings">系统设置</x:String>
<x:String x:Key="PageReports">报表统计</x:String>
<x:String x:Key="PageHelp">帮助中心</x:String>
<x:String x:Key="PageIcons">图标库</x:String>
<!-- 通用文本 -->
<x:String x:Key="Loading">加载中...</x:String>
<x:String x:Key="Error">错误</x:String>
<x:String x:Key="Success">成功</x:String>
<x:String x:Key="Warning">警告</x:String>
<x:String x:Key="Info">信息</x:String>
<x:String x:Key="Confirm">确认</x:String>
<x:String x:Key="Cancel">取消</x:String>
<x:String x:Key="Save">保存</x:String>
<x:String x:Key="Delete">删除</x:String>
<x:String x:Key="Edit">编辑</x:String>
<x:String x:Key="Add">添加</x:String>
<x:String x:Key="Search">搜索</x:String>
<x:String x:Key="Filter">筛选</x:String>
<x:String x:Key="Export">导出</x:String>
<x:String x:Key="Import">导入</x:String>
<!-- 状态文本 -->
<x:String x:Key="StatusActive">活跃</x:String>
<x:String x:Key="StatusInactive">非活跃</x:String>
<x:String x:Key="StatusPending">待处理</x:String>
<x:String x:Key="StatusCompleted">已完成</x:String>
<x:String x:Key="StatusFailed">失败</x:String>
<!-- 用户管理相关 -->
<x:String x:Key="UserList">用户列表</x:String>
<x:String x:Key="UserName">用户名</x:String>
<x:String x:Key="UserEmail">邮箱</x:String>
<x:String x:Key="UserRole">角色</x:String>
<x:String x:Key="UserStatus">状态</x:String>
<x:String x:Key="UserCreateTime">创建时间</x:String>
<x:String x:Key="UserLastLogin">最后登录</x:String>
<!-- 设置页面相关 -->
<x:String x:Key="SettingsGeneral">常规设置</x:String>
<x:String x:Key="SettingsAppearance">外观</x:String>
<x:String x:Key="SettingsNotifications">通知</x:String>
<x:String x:Key="SettingsPerformance">性能</x:String>
<x:String x:Key="SettingsLanguage">语言</x:String>
<x:String x:Key="SettingsTheme">主题</x:String>
<!-- 仪表板相关 -->
<x:String x:Key="DashboardOverview">概览</x:String>
<x:String x:Key="DashboardStats">统计</x:String>
<x:String x:Key="DashboardCharts">图表</x:String>
<x:String x:Key="DashboardRecent">最近活动</x:String>
<x:String x:Key="DashboardQuickActions">快速操作</x:String>
<!-- 报表相关 -->
<x:String x:Key="ReportGenerate">生成报表</x:String>
<x:String x:Key="ReportExport">导出报表</x:String>
<x:String x:Key="ReportDateRange">日期范围</x:String>
<x:String x:Key="ReportType">报表类型</x:String>
<x:String x:Key="ReportFormat">格式</x:String>
<!-- 帮助相关 -->
<x:String x:Key="HelpDocumentation">文档</x:String>
<x:String x:Key="HelpFAQ">常见问题</x:String>
<x:String x:Key="HelpContact">联系支持</x:String>
<x:String x:Key="HelpAbout">关于</x:String>
<x:String x:Key="HelpVersion">版本</x:String>
<x:String x:Key="HelpCopyright">版权</x:String>
</ResourceDictionary>

43
Services/ApiService.cs

@ -0,0 +1,43 @@
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
namespace MyAvaloniaApp.Services;
/// <summary>
/// API 服务实现
/// </summary>
public class ApiService : IApiService
{
private readonly ILogger<ApiService>? _logger;
public ApiService(ILogger<ApiService>? logger = null)
{
_logger = logger;
_logger?.LogInformation("ApiService 已创建");
}
public async Task<string> GetApiDataAsync(string endpoint)
{
_logger?.LogInformation("调用 API: {Endpoint}", endpoint);
// 模拟 API 调用
await Task.Delay(500);
var result = $"API 响应数据来自 {endpoint} - {DateTime.Now:HH:mm:ss}";
_logger?.LogDebug("API 响应: {Result}", result);
return result;
}
public async Task<bool> PostDataAsync(string endpoint, object data)
{
_logger?.LogInformation("POST 数据到 API: {Endpoint}", endpoint);
// 模拟 API 调用
await Task.Delay(300);
_logger?.LogDebug("数据已发送: {Data}", data);
return true;
}
}

42
Services/DataService.cs

@ -0,0 +1,42 @@
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
namespace MyAvaloniaApp.Services;
/// <summary>
/// 数据服务实现
/// </summary>
public class DataService : IDataService
{
private readonly ILogger<DataService>? _logger;
private string _data = "示例数据";
public DataService(ILogger<DataService>? logger = null)
{
_logger = logger;
_logger?.LogInformation("DataService 已创建");
}
public string GetData()
{
_logger?.LogDebug("获取数据: {Data}", _data);
return _data;
}
public async Task<string> GetDataAsync()
{
_logger?.LogDebug("异步获取数据");
// 模拟异步操作
await Task.Delay(100);
return _data;
}
public void SaveData(string data)
{
_data = data;
_logger?.LogInformation("数据已保存: {Data}", data);
}
}

12
Services/IApiService.cs

@ -0,0 +1,12 @@
using System.Threading.Tasks;
namespace MyAvaloniaApp.Services;
/// <summary>
/// API 服务接口
/// </summary>
public interface IApiService
{
Task<string> GetApiDataAsync(string endpoint);
Task<bool> PostDataAsync(string endpoint, object data);
}

13
Services/IDataService.cs

@ -0,0 +1,13 @@
using System.Threading.Tasks;
namespace MyAvaloniaApp.Services;
/// <summary>
/// 数据服务接口
/// </summary>
public interface IDataService
{
string GetData();
Task<string> GetDataAsync();
void SaveData(string data);
}

43
Services/IResourceService.cs

@ -0,0 +1,43 @@
using System;
using System.Globalization;
namespace MyAvaloniaApp.Services
{
/// <summary>
/// 资源服务接口,用于管理多语言资源
/// </summary>
public interface IResourceService
{
/// <summary>
/// 获取字符串资源
/// </summary>
/// <param name="key">资源键</param>
/// <returns>资源值</returns>
string GetString(string key);
/// <summary>
/// 获取字符串资源,支持格式化参数
/// </summary>
/// <param name="key">资源键</param>
/// <param name="args">格式化参数</param>
/// <returns>格式化后的资源值</returns>
string GetString(string key, params object[] args);
/// <summary>
/// 设置当前语言
/// </summary>
/// <param name="culture">文化信息</param>
void SetCulture(CultureInfo culture);
/// <summary>
/// 获取当前语言
/// </summary>
/// <returns>当前文化信息</returns>
CultureInfo GetCurrentCulture();
/// <summary>
/// 语言变更事件
/// </summary>
event EventHandler<CultureInfo>? CultureChanged;
}
}

90
Services/LanguageManager.cs

@ -0,0 +1,90 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
namespace MyAvaloniaApp.Services
{
/// <summary>
/// 语言管理器,用于管理应用程序的语言设置
/// </summary>
public class LanguageManager
{
private readonly IResourceService _resourceService;
private CultureInfo _currentCulture;
public event EventHandler<CultureInfo>? LanguageChanged;
public LanguageManager(IResourceService resourceService)
{
_resourceService = resourceService;
_currentCulture = CultureInfo.CurrentCulture;
}
/// <summary>
/// 获取当前语言
/// </summary>
public CultureInfo CurrentCulture => _currentCulture;
/// <summary>
/// 获取当前语言名称
/// </summary>
public string CurrentLanguageName => _currentCulture.Name.StartsWith("zh") ? "中文" : "English";
/// <summary>
/// 切换语言
/// </summary>
/// <param name="culture">目标语言文化信息</param>
public async Task SwitchLanguageAsync(CultureInfo culture)
{
if (_currentCulture != culture)
{
_currentCulture = culture;
_resourceService.SetCulture(culture);
// 触发语言变更事件
LanguageChanged?.Invoke(this, culture);
// 这里可以添加其他语言切换逻辑,比如重新加载UI等
await OnLanguageChangedAsync(culture);
}
}
/// <summary>
/// 切换到中文
/// </summary>
public async Task SwitchToChineseAsync()
{
await SwitchLanguageAsync(new CultureInfo("zh-CN"));
}
/// <summary>
/// 切换到英文
/// </summary>
public async Task SwitchToEnglishAsync()
{
await SwitchLanguageAsync(new CultureInfo("en-US"));
}
/// <summary>
/// 切换语言(中文/英文)
/// </summary>
public async Task ToggleLanguageAsync()
{
if (_currentCulture.Name.StartsWith("zh"))
{
await SwitchToEnglishAsync();
}
else
{
await SwitchToChineseAsync();
}
}
private async Task OnLanguageChangedAsync(CultureInfo culture)
{
// 这里可以添加语言切换后的处理逻辑
// 比如重新加载页面内容、更新UI等
await Task.CompletedTask;
}
}
}

128
Services/ResourceService.cs

@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Resources;
using System.Reflection;
namespace MyAvaloniaApp.Services
{
/// <summary>
/// 资源服务实现,用于管理多语言资源
/// </summary>
public class ResourceService : IResourceService
{
private readonly Dictionary<string, string> _resources;
private CultureInfo _currentCulture;
public event EventHandler<CultureInfo>? CultureChanged;
public ResourceService()
{
_resources = new Dictionary<string, string>();
_currentCulture = CultureInfo.CurrentCulture;
LoadResources();
}
public string GetString(string key)
{
return _resources.TryGetValue(key, out var value) ? value : key;
}
public string GetString(string key, params object[] args)
{
var format = GetString(key);
try
{
return string.Format(format, args);
}
catch
{
return format;
}
}
public void SetCulture(CultureInfo culture)
{
if (_currentCulture != culture)
{
_currentCulture = culture;
LoadResources();
CultureChanged?.Invoke(this, culture);
}
}
public CultureInfo GetCurrentCulture()
{
return _currentCulture;
}
private void LoadResources()
{
_resources.Clear();
// 根据当前语言加载对应的资源
var resourceFileName = _currentCulture.Name.StartsWith("zh") ? "Strings.zh-CN" : "Strings.en";
// 这里我们使用硬编码的方式,实际项目中可以使用ResourceManager
LoadHardcodedResources(resourceFileName);
}
private void LoadHardcodedResources(string resourceSet)
{
if (resourceSet == "Strings.zh-CN")
{
// 中文资源
_resources["AppTitle"] = "系统管理";
_resources["AppSubtitle"] = "Management System";
_resources["NavDashboard"] = "仪表板";
_resources["NavUsers"] = "用户管理";
_resources["NavSettings"] = "系统设置";
_resources["NavReports"] = "报表统计";
_resources["NavHelp"] = "帮助中心";
_resources["HeaderTitle"] = "仪表板";
_resources["HeaderSubtitle"] = "系统概览";
_resources["BtnRefresh"] = "刷新";
_resources["BtnSettings"] = "设置";
_resources["BtnMinimize"] = "最小化";
_resources["BtnMaximize"] = "最大化";
_resources["BtnRestore"] = "还原";
_resources["BtnClose"] = "关闭";
_resources["BtnCloseTab"] = "关闭标签页";
_resources["VersionInfo"] = "版本信息";
_resources["VersionNumber"] = "v1.0.0";
_resources["PageDashboard"] = "仪表板";
_resources["PageUsers"] = "用户管理";
_resources["PageSettings"] = "系统设置";
_resources["PageReports"] = "报表统计";
_resources["PageHelp"] = "帮助中心";
}
else
{
// 英文资源
_resources["AppTitle"] = "Management System";
_resources["AppSubtitle"] = "Management System";
_resources["NavDashboard"] = "Dashboard";
_resources["NavUsers"] = "User Management";
_resources["NavSettings"] = "System Settings";
_resources["NavReports"] = "Reports";
_resources["NavHelp"] = "Help Center";
_resources["HeaderTitle"] = "Dashboard";
_resources["HeaderSubtitle"] = "System Overview";
_resources["BtnRefresh"] = "Refresh";
_resources["BtnSettings"] = "Settings";
_resources["BtnMinimize"] = "Minimize";
_resources["BtnMaximize"] = "Maximize";
_resources["BtnRestore"] = "Restore";
_resources["BtnClose"] = "Close";
_resources["BtnCloseTab"] = "Close Tab";
_resources["VersionInfo"] = "Version Information";
_resources["VersionNumber"] = "v1.0.0";
_resources["PageDashboard"] = "Dashboard";
_resources["PageUsers"] = "User Management";
_resources["PageSettings"] = "System Settings";
_resources["PageReports"] = "Reports";
_resources["PageHelp"] = "Help Center";
}
}
}
}

19
ViewModels/AppViewModel.cs

@ -0,0 +1,19 @@
using ReactiveUI;
using System;
namespace MyAvaloniaApp.ViewModels;
/// <summary>
/// 应用程序级别的 ViewModel,实现 IScreen 接口
/// </summary>
public class AppViewModel : ReactiveObject, IScreen
{
public RoutingState Router { get; } = new RoutingState();
public AppViewModel()
{
// 配置路由 - 默认导航到主窗口
// 注意:这里应该通过依赖注入获取 MainWindowViewModel
// Router.Navigate.Execute(new MainWindowViewModel());
}
}

425
ViewModels/MainWindowViewModel.cs

@ -0,0 +1,425 @@
using Microsoft.Extensions.Logging;
using MyAvaloniaApp.Services;
using ReactiveUI;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Threading.Tasks;
namespace MyAvaloniaApp.ViewModels;
/// <summary>
/// 主窗口的 ViewModel
/// </summary>
public class MainWindowViewModel : ReactiveObject
{
private string _title = "My Avalonia App - 导航栏 + 标签页";
private string _headerTitle = "系统管理平台";
private string _headerSubtitle = "欢迎使用现代化管理界面";
private ObservableCollection<NavigationItem> _navigationItems = new();
private ObservableCollection<TabItem> _tabs = new();
private NavigationItem? _selectedNavigationItem;
private TabItem? _selectedTab;
private readonly ILogger<MainWindowViewModel>? _logger;
private readonly IDataService? _dataService;
private readonly IResourceService? _resourceService;
public string Title
{
get => _title;
set => this.RaiseAndSetIfChanged(ref _title, value);
}
public string HeaderTitle
{
get => _headerTitle;
set => this.RaiseAndSetIfChanged(ref _headerTitle, value);
}
public string HeaderSubtitle
{
get => _headerSubtitle;
set => this.RaiseAndSetIfChanged(ref _headerSubtitle, value);
}
public ObservableCollection<NavigationItem> NavigationItems
{
get => _navigationItems;
set => this.RaiseAndSetIfChanged(ref _navigationItems, value);
}
public ObservableCollection<TabItem> Tabs
{
get => _tabs;
set => this.RaiseAndSetIfChanged(ref _tabs, value);
}
public NavigationItem? SelectedNavigationItem
{
get => _selectedNavigationItem;
set => this.RaiseAndSetIfChanged(ref _selectedNavigationItem, value);
}
public TabItem? SelectedTab
{
get => _selectedTab;
set => this.RaiseAndSetIfChanged(ref _selectedTab, value);
}
// 响应式命令
public ReactiveCommand<NavigationItem, Unit> NavigateCommand { get; }
public ReactiveCommand<TabItem, Unit> CloseTabCommand { get; }
public ReactiveCommand<TabItem, Unit> SelectTabCommand { get; }
public MainWindowViewModel(ILogger<MainWindowViewModel>? logger = null, IDataService? dataService = null, IResourceService? resourceService = null)
{
_logger = logger;
_dataService = dataService;
_resourceService = resourceService;
_logger?.LogInformation("MainWindowViewModel 已创建");
// 初始化导航项
InitializeNavigationItems();
// 初始化标签页
InitializeTabs();
// 创建导航命令
NavigateCommand = ReactiveCommand.Create<NavigationItem>(NavigateToPage);
// 创建关闭标签页命令
CloseTabCommand = ReactiveCommand.Create<TabItem>(CloseTab);
// 创建选择标签页命令
SelectTabCommand = ReactiveCommand.Create<TabItem>(SelectTab);
// 监听导航项选择变化
this.WhenAnyValue(x => x.SelectedNavigationItem)
.Where(item => item != null)
.Subscribe(item => _logger?.LogInformation("导航到: {Title}", item!.Title));
// 监听标签页选择变化
this.WhenAnyValue(x => x.SelectedTab)
.Where(tab => tab != null)
.Subscribe(tab => _logger?.LogInformation("切换到标签页: {Title}", tab!.Title));
}
private void InitializeNavigationItems()
{
_navigationItems = new ObservableCollection<NavigationItem>
{
new NavigationItem
{
Id = "dashboard",
Title = _resourceService?.GetString("NavDashboard") ?? "仪表板",
IconType = HeroIconsAvalonia.Enums.IconType.Home,
Content = new Views.Pages.DashboardPageView { DataContext = new Pages.DashboardPageViewModel() }
},
new NavigationItem
{
Id = "users",
Title = _resourceService?.GetString("NavUsers") ?? "用户管理",
IconType = HeroIconsAvalonia.Enums.IconType.Users,
Children = new ObservableCollection<NavigationItem>
{
new NavigationItem
{
Id = "users-list",
Title = "用户列表",
IconType = HeroIconsAvalonia.Enums.IconType.UserGroup,
Content = new Views.Pages.UsersPageView { DataContext = new Pages.UsersPageViewModel() }
},
new NavigationItem
{
Id = "users-roles",
Title = "角色管理",
IconType = HeroIconsAvalonia.Enums.IconType.ShieldCheck,
Content = new Views.Pages.UsersPageView { DataContext = new Pages.UsersPageViewModel() }
},
new NavigationItem
{
Id = "users-permissions",
Title = "权限设置",
IconType = HeroIconsAvalonia.Enums.IconType.Key,
Content = new Views.Pages.UsersPageView { DataContext = new Pages.UsersPageViewModel() }
}
}
},
new NavigationItem
{
Id = "settings",
Title = _resourceService?.GetString("NavSettings") ?? "系统设置",
IconType = HeroIconsAvalonia.Enums.IconType.Cog6Tooth,
Children = new ObservableCollection<NavigationItem>
{
new NavigationItem
{
Id = "settings-general",
Title = "常规设置",
IconType = HeroIconsAvalonia.Enums.IconType.Cog,
Content = new Views.Pages.SettingsPageView { DataContext = new Pages.SettingsPageViewModel() }
},
new NavigationItem
{
Id = "settings-security",
Title = "安全设置",
IconType = HeroIconsAvalonia.Enums.IconType.LockClosed,
Content = new Views.Pages.SettingsPageView { DataContext = new Pages.SettingsPageViewModel() }
},
new NavigationItem
{
Id = "settings-backup",
Title = "备份恢复",
IconType = HeroIconsAvalonia.Enums.IconType.CloudArrowUp,
Content = new Views.Pages.SettingsPageView { DataContext = new Pages.SettingsPageViewModel() }
}
}
},
new NavigationItem
{
Id = "reports",
Title = _resourceService?.GetString("NavReports") ?? "报表统计",
IconType = HeroIconsAvalonia.Enums.IconType.ChartBar,
Content = new Views.Pages.ReportsPageView { DataContext = new Pages.ReportsPageViewModel() }
},
new NavigationItem
{
Id = "help",
Title = _resourceService?.GetString("NavHelp") ?? "帮助中心",
IconType = HeroIconsAvalonia.Enums.IconType.QuestionMarkCircle,
Content = new Views.Pages.HelpPageView { DataContext = new Pages.HelpPageViewModel() }
},
new NavigationItem
{
Id = "icons",
Title = _resourceService?.GetString("NavIcons") ?? "图标库",
IconType = HeroIconsAvalonia.Enums.IconType.Sparkles,
Content = new Views.Pages.IconsPageView { DataContext = new Pages.IconsPageViewModel() }
}
};
// 默认选中第一个导航项
if (_navigationItems.Count > 0)
{
_navigationItems[0].IsSelected = true;
SelectedNavigationItem = _navigationItems[0];
}
}
private void InitializeTabs()
{
_tabs = new ObservableCollection<TabItem>();
// 默认添加仪表板标签页
if (_navigationItems.Count > 0)
{
var dashboardNav = _navigationItems.FirstOrDefault(x => x.Id == "dashboard");
if (dashboardNav != null)
{
var dashboardTab = new TabItem
{
Id = "dashboard",
Title = _resourceService?.GetString("PageDashboard") ?? "仪表板",
IconType = HeroIconsAvalonia.Enums.IconType.Home,
Content = dashboardNav.Content,
IsSelected = true,
CanClose = false
};
_tabs.Add(dashboardTab);
SelectedTab = dashboardTab;
}
}
}
private void NavigateToPage(NavigationItem navigationItem)
{
if (navigationItem == null) return;
// 检查是否是子级菜单项
bool isChildItem = _navigationItems.Any(parent => parent.Children.Contains(navigationItem));
if (isChildItem)
{
// 子级菜单项:只选中当前项,不影响父级菜单的展开状态
// 取消所有导航项的选中状态
foreach (var item in _navigationItems)
{
item.IsSelected = false;
foreach (var child in item.Children)
{
child.IsSelected = false;
}
}
// 设置当前子项为选中状态
navigationItem.IsSelected = true;
SelectedNavigationItem = navigationItem;
// 创建标签页
CreateTabForNavigationItem(navigationItem);
_logger?.LogInformation("导航到子页面: {Title}", navigationItem.Title);
}
else if (navigationItem.HasChildren)
{
// 父级菜单项:处理展开/收起逻辑
// 检查是否已经展开
if (navigationItem.IsExpanded)
{
// 如果已经展开,则收起
navigationItem.IsExpanded = false;
// 取消所有导航项的选中状态
foreach (var item in _navigationItems)
{
item.IsSelected = false;
foreach (var child in item.Children)
{
child.IsSelected = false;
}
}
// 清除 SelectedNavigationItem
SelectedNavigationItem = null;
_logger?.LogInformation("收起导航项: {Title}", navigationItem.Title);
}
else
{
// 如果未展开,则展开并选中第一个子项
// 先收起其他所有展开的父级导航项
foreach (var item in _navigationItems)
{
if (item != navigationItem && item.HasChildren)
{
item.IsExpanded = false;
item.IsSelected = false;
foreach (var child in item.Children)
{
child.IsSelected = false;
}
}
}
// 展开当前导航项
navigationItem.IsExpanded = true;
// 选中第一个子项
if (navigationItem.Children.Count > 0)
{
var firstChild = navigationItem.Children[0];
firstChild.IsSelected = true;
SelectedNavigationItem = firstChild;
// 为第一个子项创建标签页
CreateTabForNavigationItem(firstChild);
}
_logger?.LogInformation("展开导航项: {Title}", navigationItem.Title);
}
}
else
{
// 无子项的父级导航项,直接选中
// 先收起所有展开的父级导航项
foreach (var item in _navigationItems)
{
if (item.HasChildren)
{
item.IsExpanded = false;
}
item.IsSelected = false;
foreach (var child in item.Children)
{
child.IsSelected = false;
}
}
// 设置当前导航项为选中状态
navigationItem.IsSelected = true;
SelectedNavigationItem = navigationItem;
// 创建标签页
CreateTabForNavigationItem(navigationItem);
_logger?.LogInformation("导航到页面: {Title}", navigationItem.Title);
}
}
private void CreateTabForNavigationItem(NavigationItem navigationItem)
{
// 检查是否已经存在对应的标签页
var existingTab = _tabs.FirstOrDefault(t => t.Id == navigationItem.Id);
if (existingTab != null)
{
// 如果标签页已存在,选中它
foreach (var tab in _tabs)
{
tab.IsSelected = false;
}
existingTab.IsSelected = true;
SelectedTab = existingTab;
}
else
{
// 创建新的标签页
var newTab = new TabItem
{
Id = navigationItem.Id,
Title = navigationItem.Title,
IconType = navigationItem.IconType,
Content = navigationItem.Content,
IsSelected = true,
CanClose = navigationItem.Id != "dashboard" // 仪表板标签页不能关闭
};
// 取消其他标签页的选中状态
foreach (var tab in _tabs)
{
tab.IsSelected = false;
}
_tabs.Add(newTab);
SelectedTab = newTab;
}
}
private void SelectTab(TabItem tab)
{
if (tab == null) return;
// 取消所有标签页的选中状态
foreach (var t in _tabs)
{
t.IsSelected = false;
}
// 设置当前标签页为选中状态
tab.IsSelected = true;
SelectedTab = tab;
_logger?.LogInformation("选择标签页: {Title}", tab.Title);
}
private void CloseTab(TabItem tab)
{
if (tab == null || !tab.CanClose) return;
var tabIndex = _tabs.IndexOf(tab);
_tabs.Remove(tab);
// 如果关闭的是当前选中的标签页,需要选择其他标签页
if (tab.IsSelected && _tabs.Count > 0)
{
var newSelectedIndex = Math.Min(tabIndex, _tabs.Count - 1);
_tabs[newSelectedIndex].IsSelected = true;
SelectedTab = _tabs[newSelectedIndex];
}
_logger?.LogInformation("关闭标签页: {Title}", tab.Title);
}
}

82
ViewModels/NavigationItem.cs

@ -0,0 +1,82 @@
using ReactiveUI;
using HeroIconsAvalonia.Enums;
using System.Collections.ObjectModel;
namespace MyAvaloniaApp.ViewModels;
/// <summary>
/// 导航项模型
/// </summary>
public class NavigationItem : ReactiveObject
{
private string _title = string.Empty;
private IconType _iconType = IconType.Home;
private bool _isSelected;
private bool _isExpanded;
private object? _content;
private ObservableCollection<NavigationItem> _children = new();
/// <summary>
/// 导航项标题
/// </summary>
public string Title
{
get => _title;
set => this.RaiseAndSetIfChanged(ref _title, value);
}
/// <summary>
/// 导航项图标类型
/// </summary>
public IconType IconType
{
get => _iconType;
set => this.RaiseAndSetIfChanged(ref _iconType, value);
}
/// <summary>
/// 是否选中
/// </summary>
public bool IsSelected
{
get => _isSelected;
set => this.RaiseAndSetIfChanged(ref _isSelected, value);
}
/// <summary>
/// 是否展开(用于二级导航)
/// </summary>
public bool IsExpanded
{
get => _isExpanded;
set => this.RaiseAndSetIfChanged(ref _isExpanded, value);
}
/// <summary>
/// 导航项内容
/// </summary>
public object? Content
{
get => _content;
set => this.RaiseAndSetIfChanged(ref _content, value);
}
/// <summary>
/// 子导航项集合(用于二级导航)
/// </summary>
public ObservableCollection<NavigationItem> Children
{
get => _children;
set => this.RaiseAndSetIfChanged(ref _children, value);
}
/// <summary>
/// 导航项标识符
/// </summary>
public string Id { get; set; } = string.Empty;
/// <summary>
/// 是否有子项
/// </summary>
public bool HasChildren => Children?.Count > 0;
}

50
ViewModels/Pages/DashboardPageViewModel.cs

@ -0,0 +1,50 @@
using ReactiveUI;
namespace MyAvaloniaApp.ViewModels.Pages;
/// <summary>
/// 仪表板页面ViewModel
/// </summary>
public class DashboardPageViewModel : ReactiveObject
{
private string _welcomeMessage = "欢迎使用仪表板!";
private int _totalUsers = 1250;
private int _activeSessions = 45;
private double _systemLoad = 75.5;
/// <summary>
/// 欢迎消息
/// </summary>
public string WelcomeMessage
{
get => _welcomeMessage;
set => this.RaiseAndSetIfChanged(ref _welcomeMessage, value);
}
/// <summary>
/// 总用户数
/// </summary>
public int TotalUsers
{
get => _totalUsers;
set => this.RaiseAndSetIfChanged(ref _totalUsers, value);
}
/// <summary>
/// 活跃会话数
/// </summary>
public int ActiveSessions
{
get => _activeSessions;
set => this.RaiseAndSetIfChanged(ref _activeSessions, value);
}
/// <summary>
/// 系统负载
/// </summary>
public double SystemLoad
{
get => _systemLoad;
set => this.RaiseAndSetIfChanged(ref _systemLoad, value);
}
}

40
ViewModels/Pages/HelpPageViewModel.cs

@ -0,0 +1,40 @@
using ReactiveUI;
namespace MyAvaloniaApp.ViewModels.Pages;
/// <summary>
/// 帮助中心页面ViewModel
/// </summary>
public class HelpPageViewModel : ReactiveObject
{
private string _welcomeMessage = "欢迎使用帮助中心!";
private string _version = "v1.0.0";
private string _lastUpdate = "2025年1月10日";
/// <summary>
/// 欢迎消息
/// </summary>
public string WelcomeMessage
{
get => _welcomeMessage;
set => this.RaiseAndSetIfChanged(ref _welcomeMessage, value);
}
/// <summary>
/// 版本信息
/// </summary>
public string Version
{
get => _version;
set => this.RaiseAndSetIfChanged(ref _version, value);
}
/// <summary>
/// 最后更新时间
/// </summary>
public string LastUpdate
{
get => _lastUpdate;
set => this.RaiseAndSetIfChanged(ref _lastUpdate, value);
}
}

145
ViewModels/Pages/IconsPageViewModel.cs

@ -0,0 +1,145 @@
using Microsoft.Extensions.Logging;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Threading.Tasks;
using HeroIconsAvalonia;
using HeroIconsAvalonia.Controls;
using HeroIconsAvalonia.Enums;
using Avalonia.Controls;
using Avalonia;
using Avalonia.Layout;
namespace MyAvaloniaApp.ViewModels.Pages;
/// <summary>
/// 图标导航页面的 ViewModel
/// </summary>
public class IconsPageViewModel : ReactiveObject
{
private ObservableCollection<HeroIconItem> _heroIcons = new();
private HeroIconItem? _selectedIcon;
private readonly ILogger<IconsPageViewModel>? _logger;
public ObservableCollection<HeroIconItem> HeroIcons
{
get => _heroIcons;
set => this.RaiseAndSetIfChanged(ref _heroIcons, value);
}
public HeroIconItem? SelectedIcon
{
get => _selectedIcon;
set => this.RaiseAndSetIfChanged(ref _selectedIcon, value);
}
// 响应式命令
public ReactiveCommand<HeroIconItem, Unit> CopyIconCommand { get; }
public ReactiveCommand<HeroIconItem, Unit> SelectIconCommand { get; }
public IconsPageViewModel(ILogger<IconsPageViewModel>? logger = null)
{
_logger = logger;
_logger?.LogInformation("IconsPageViewModel 已创建");
// 初始化图标数据
InitializeHeroIcons();
// 创建命令
CopyIconCommand = ReactiveCommand.Create<HeroIconItem>(CopyIconToClipboard);
SelectIconCommand = ReactiveCommand.Create<HeroIconItem>(SelectIcon);
// 监听图标选择变化
this.WhenAnyValue(x => x.SelectedIcon)
.Where(icon => icon != null)
.Subscribe(icon => _logger?.LogInformation("选择图标: {Name}", icon!.DisplayName));
}
private void InitializeHeroIcons()
{
try
{
// 获取所有 IconType 枚举值
var iconTypes = Enum.GetValues(typeof(IconType)).Cast<IconType>().ToList();
_logger?.LogInformation("开始初始化 {Count} 个 HeroIcons 图标", iconTypes.Count);
// 添加 Outline 样式的图标
foreach (var iconType in iconTypes)
{
HeroIcons.Add(new HeroIconItem
{
IconType = iconType,
IconKind = IconKind.Outline
});
}
// 添加 Solid 样式的图标
foreach (var iconType in iconTypes)
{
HeroIcons.Add(new HeroIconItem
{
IconType = iconType,
IconKind = IconKind.Solid
});
}
_logger?.LogInformation("成功初始化 {Count} 个 HeroIcons 图标", HeroIcons.Count);
}
catch (Exception ex)
{
_logger?.LogError(ex, "初始化 HeroIcons 图标时发生错误");
}
}
private void CopyIconToClipboard(HeroIconItem icon)
{
if (icon == null) return;
// 这里可以实现复制到剪贴板的逻辑
_logger?.LogInformation("复制图标到剪贴板: {Name}", icon.DisplayName);
// 可以添加通知用户复制成功的逻辑
}
private void SelectIcon(HeroIconItem icon)
{
if (icon == null) return;
SelectedIcon = icon;
_logger?.LogInformation("选择图标: {Name}", icon.DisplayName);
}
}
/// <summary>
/// HeroIcons 图标数据模型
/// </summary>
public class HeroIconItem : ReactiveObject
{
private IconType _iconType;
private IconKind _iconKind = IconKind.Outline;
public IconType IconType
{
get => _iconType;
set => this.RaiseAndSetIfChanged(ref _iconType, value);
}
public IconKind IconKind
{
get => _iconKind;
set => this.RaiseAndSetIfChanged(ref _iconKind, value);
}
public string DisplayName => $"{IconType} ({IconKind})";
}

50
ViewModels/Pages/ReportsPageViewModel.cs

@ -0,0 +1,50 @@
using ReactiveUI;
namespace MyAvaloniaApp.ViewModels.Pages;
/// <summary>
/// 报表统计页面ViewModel
/// </summary>
public class ReportsPageViewModel : ReactiveObject
{
private string _welcomeMessage = "欢迎使用报表统计功能!";
private int _totalReports = 156;
private int _monthlyReports = 23;
private double _averageScore = 87.5;
/// <summary>
/// 欢迎消息
/// </summary>
public string WelcomeMessage
{
get => _welcomeMessage;
set => this.RaiseAndSetIfChanged(ref _welcomeMessage, value);
}
/// <summary>
/// 总报表数
/// </summary>
public int TotalReports
{
get => _totalReports;
set => this.RaiseAndSetIfChanged(ref _totalReports, value);
}
/// <summary>
/// 月度报表数
/// </summary>
public int MonthlyReports
{
get => _monthlyReports;
set => this.RaiseAndSetIfChanged(ref _monthlyReports, value);
}
/// <summary>
/// 平均评分
/// </summary>
public double AverageScore
{
get => _averageScore;
set => this.RaiseAndSetIfChanged(ref _averageScore, value);
}
}

50
ViewModels/Pages/SettingsPageViewModel.cs

@ -0,0 +1,50 @@
using ReactiveUI;
namespace MyAvaloniaApp.ViewModels.Pages;
/// <summary>
/// 设置页面ViewModel
/// </summary>
public class SettingsPageViewModel : ReactiveObject
{
private bool _darkMode = false;
private string _language = "zh-CN";
private bool _notifications = true;
private int _refreshInterval = 30;
/// <summary>
/// 深色模式
/// </summary>
public bool DarkMode
{
get => _darkMode;
set => this.RaiseAndSetIfChanged(ref _darkMode, value);
}
/// <summary>
/// 语言设置
/// </summary>
public string Language
{
get => _language;
set => this.RaiseAndSetIfChanged(ref _language, value);
}
/// <summary>
/// 通知设置
/// </summary>
public bool Notifications
{
get => _notifications;
set => this.RaiseAndSetIfChanged(ref _notifications, value);
}
/// <summary>
/// 刷新间隔(秒)
/// </summary>
public int RefreshInterval
{
get => _refreshInterval;
set => this.RaiseAndSetIfChanged(ref _refreshInterval, value);
}
}

45
ViewModels/Pages/UsersPageViewModel.cs

@ -0,0 +1,45 @@
using ReactiveUI;
using System.Collections.ObjectModel;
namespace MyAvaloniaApp.ViewModels.Pages;
/// <summary>
/// 用户管理页面ViewModel
/// </summary>
public class UsersPageViewModel : ReactiveObject
{
private ObservableCollection<UserInfo> _users;
public UsersPageViewModel()
{
_users = new ObservableCollection<UserInfo>
{
new UserInfo { Id = 1, Name = "张三", Email = "zhangsan@example.com", Role = "管理员", Status = "在线" },
new UserInfo { Id = 2, Name = "李四", Email = "lisi@example.com", Role = "用户", Status = "离线" },
new UserInfo { Id = 3, Name = "王五", Email = "wangwu@example.com", Role = "编辑", Status = "在线" },
new UserInfo { Id = 4, Name = "赵六", Email = "zhaoliu@example.com", Role = "用户", Status = "在线" },
new UserInfo { Id = 5, Name = "钱七", Email = "qianqi@example.com", Role = "管理员", Status = "离线" }
};
}
/// <summary>
/// 用户列表
/// </summary>
public ObservableCollection<UserInfo> Users
{
get => _users;
set => this.RaiseAndSetIfChanged(ref _users, value);
}
}
/// <summary>
/// 用户信息模型
/// </summary>
public class UserInfo
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Role { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
}

71
ViewModels/TabItem.cs

@ -0,0 +1,71 @@
using ReactiveUI;
using HeroIconsAvalonia.Enums;
namespace MyAvaloniaApp.ViewModels;
/// <summary>
/// 标签页项模型
/// </summary>
public class TabItem : ReactiveObject
{
private string _title = string.Empty;
private IconType _iconType = IconType.Home;
private object? _content;
private bool _isSelected;
private bool _canClose = true;
/// <summary>
/// 标签页标题
/// </summary>
public string Title
{
get => _title;
set => this.RaiseAndSetIfChanged(ref _title, value);
}
/// <summary>
/// 标签页图标类型
/// </summary>
public IconType IconType
{
get => _iconType;
set => this.RaiseAndSetIfChanged(ref _iconType, value);
}
/// <summary>
/// 标签页内容
/// </summary>
public object? Content
{
get => _content;
set => this.RaiseAndSetIfChanged(ref _content, value);
}
/// <summary>
/// 是否选中
/// </summary>
public bool IsSelected
{
get => _isSelected;
set => this.RaiseAndSetIfChanged(ref _isSelected, value);
}
/// <summary>
/// 是否可以关闭
/// </summary>
public bool CanClose
{
get => _canClose;
set => this.RaiseAndSetIfChanged(ref _canClose, value);
}
/// <summary>
/// 标签页标识符
/// </summary>
public string Id { get; set; } = string.Empty;
/// <summary>
/// 标签页类型
/// </summary>
public string Type { get; set; } = string.Empty;
}

250
Views/Pages/DashboardPageView.axaml

@ -0,0 +1,250 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:vm="using:MyAvaloniaApp.ViewModels.Pages"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
x:Class="MyAvaloniaApp.Views.Pages.DashboardPageView"
x:DataType="vm:DashboardPageViewModel">
<Design.DataContext>
<vm:DashboardPageViewModel />
</Design.DataContext>
<Grid>
<!-- 统计卡片 -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 统计卡片行 -->
<Grid Grid.Row="0" Margin="0,0,0,30">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 总用户数卡片 -->
<Border Grid.Column="0"
Background="#3498DB"
CornerRadius="10"
Margin="0,0,15,0"
Padding="20">
<StackPanel>
<TextBlock Text="👥"
FontSize="32"
HorizontalAlignment="Center"
Margin="0,0,0,10"/>
<TextBlock Text="{Binding TotalUsers}"
FontSize="36"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="总用户数"
FontSize="14"
Foreground="White"
HorizontalAlignment="Center"
Opacity="0.9"/>
</StackPanel>
</Border>
<!-- 活跃会话卡片 -->
<Border Grid.Column="1"
Background="#E74C3C"
CornerRadius="10"
Margin="5,0,10,0"
Padding="20">
<StackPanel>
<TextBlock Text="🔗"
FontSize="32"
HorizontalAlignment="Center"
Margin="0,0,0,10"/>
<TextBlock Text="{Binding ActiveSessions}"
FontSize="36"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="活跃会话"
FontSize="14"
Foreground="White"
HorizontalAlignment="Center"
Opacity="0.9"/>
</StackPanel>
</Border>
<!-- 系统负载卡片 -->
<Border Grid.Column="2"
Background="#F39C12"
CornerRadius="10"
Margin="5,0,10,0"
Padding="20">
<StackPanel>
<TextBlock Text="⚡"
FontSize="32"
HorizontalAlignment="Center"
Margin="0,0,0,10"/>
<TextBlock Text="{Binding SystemLoad}"
FontSize="36"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="系统负载 %"
FontSize="14"
Foreground="White"
HorizontalAlignment="Center"
Opacity="0.9"/>
</StackPanel>
</Border>
<!-- 欢迎消息卡片 -->
<Border Grid.Column="3"
Background="#27AE60"
CornerRadius="10"
Margin="5,0,0,0"
Padding="20">
<StackPanel>
<TextBlock Text="🎉"
FontSize="32"
HorizontalAlignment="Center"
Margin="0,0,0,10"/>
<TextBlock Text="欢迎"
FontSize="24"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="使用系统"
FontSize="14"
Foreground="White"
HorizontalAlignment="Center"
Opacity="0.9"/>
</StackPanel>
</Border>
</Grid>
<!-- 详细信息区域 -->
<Border Grid.Row="1"
Background="#F8F9FA"
CornerRadius="10"
Padding="30">
<StackPanel>
<TextBlock Text="📈 系统状态"
FontSize="20"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,20"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧信息 -->
<StackPanel Grid.Column="0" Margin="0,0,20,0">
<TextBlock Text="系统信息"
FontSize="16"
FontWeight="Bold"
Foreground="#34495E"
Margin="0,0,0,15"/>
<StackPanel Spacing="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="操作系统:"
Foreground="#7F8C8D"
Width="100"/>
<TextBlock Grid.Column="1"
Text="Windows 11"
Foreground="#2C3E50"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="运行时间:"
Foreground="#7F8C8D"
Width="100"/>
<TextBlock Grid.Column="1"
Text="2天 14小时"
Foreground="#2C3E50"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="最后更新:"
Foreground="#7F8C8D"
Width="100"/>
<TextBlock Grid.Column="1"
Text="{Binding WelcomeMessage}"
Foreground="#2C3E50"/>
</Grid>
</StackPanel>
</StackPanel>
<!-- 右侧信息 -->
<StackPanel Grid.Column="1">
<TextBlock Text="快速操作"
FontSize="16"
FontWeight="Bold"
Foreground="#34495E"
Margin="0,0,0,15"/>
<StackPanel Spacing="10">
<Button Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="📊" FontSize="14"/>
<TextBlock Text="查看详细报表" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#E74C3C"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="👥" FontSize="14"/>
<TextBlock Text="管理用户" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#95A5A6"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="⚙️" FontSize="14"/>
<TextBlock Text="系统设置" FontSize="14"/>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</Grid>
</StackPanel>
</Border>
</Grid>
</Grid>
</UserControl>

11
Views/Pages/DashboardPageView.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace MyAvaloniaApp.Views.Pages;
public partial class DashboardPageView : UserControl
{
public DashboardPageView()
{
InitializeComponent();
}
}

225
Views/Pages/HelpPageView.axaml

@ -0,0 +1,225 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:vm="using:MyAvaloniaApp.ViewModels.Pages"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
x:Class="MyAvaloniaApp.Views.Pages.HelpPageView"
x:DataType="vm:HelpPageViewModel">
<Design.DataContext>
<vm:HelpPageViewModel />
</Design.DataContext>
<Grid>
<!-- 帮助内容 -->
<ScrollViewer>
<StackPanel Spacing="20">
<!-- 快速开始 -->
<Border Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1"
Padding="25">
<StackPanel>
<TextBlock Text="🚀 快速开始"
FontSize="18"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,15"/>
<StackPanel Spacing="10">
<TextBlock Text="1. 点击左侧导航栏中的功能模块"
FontSize="14"
Foreground="#2C3E50"/>
<TextBlock Text="2. 使用标签页切换不同的功能页面"
FontSize="14"
Foreground="#2C3E50"/>
<TextBlock Text="3. 在设置页面中配置系统参数"
FontSize="14"
Foreground="#2C3E50"/>
<TextBlock Text="4. 查看仪表板了解系统状态"
FontSize="14"
Foreground="#2C3E50"/>
</StackPanel>
</StackPanel>
</Border>
<!-- 常见问题 -->
<Border Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1"
Padding="25">
<StackPanel>
<TextBlock Text="❓ 常见问题"
FontSize="18"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,15"/>
<StackPanel Spacing="15">
<StackPanel>
<TextBlock Text="Q: 如何添加新用户?"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"/>
<TextBlock FontSize="12"
Foreground="#6C757D"
Margin="0,5,0,0">
<Run Text="A: 在用户管理页面点击"/>
<Run Text="添加用户" FontWeight="SemiBold"/>
<Run Text="按钮,填写用户信息即可。"/>
</TextBlock>
</StackPanel>
<StackPanel>
<TextBlock Text="Q: 如何修改系统设置?"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"/>
<TextBlock Text="A: 在系统设置页面中可以修改外观、通知和性能相关设置。"
FontSize="12"
Foreground="#6C757D"
Margin="0,5,0,0"/>
</StackPanel>
<StackPanel>
<TextBlock Text="Q: 标签页如何关闭?"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"/>
<TextBlock FontSize="12"
Foreground="#6C757D"
Margin="0,5,0,0">
<Run Text="A: 点击标签页右侧的"/>
<Run Text="×" FontWeight="SemiBold"/>
<Run Text="按钮即可关闭,仪表板标签页不可关闭。"/>
</TextBlock>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
<!-- 系统信息 -->
<Border Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1"
Padding="25">
<StackPanel>
<TextBlock Text="ℹ️ 系统信息"
FontSize="18"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,15"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="0,0,20,0">
<TextBlock Text="版本信息"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"
Margin="0,0,0,10"/>
<StackPanel Spacing="8">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="当前版本:"
Foreground="#6C757D"
Width="80"/>
<TextBlock Grid.Column="1"
Text="{Binding Version}"
Foreground="#2C3E50"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="最后更新:"
Foreground="#6C757D"
Width="80"/>
<TextBlock Grid.Column="1"
Text="{Binding LastUpdate}"
Foreground="#2C3E50"/>
</Grid>
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="技术支持"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"
Margin="0,0,0,10"/>
<StackPanel Spacing="8">
<TextBlock Text="📧 邮箱: support@example.com"
FontSize="12"
Foreground="#6C757D"/>
<TextBlock Text="📞 电话: 400-123-4567"
FontSize="12"
Foreground="#6C757D"/>
<TextBlock Text="🌐 网站: www.example.com"
FontSize="12"
Foreground="#6C757D"/>
</StackPanel>
</StackPanel>
</Grid>
</StackPanel>
</Border>
<!-- 操作按钮 -->
<StackPanel Orientation="Horizontal"
Spacing="15"
HorizontalAlignment="Center"
Margin="0,20,0,0">
<Button Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="📖" FontSize="14"/>
<TextBlock Text="用户手册" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#E74C3C"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="🐛" FontSize="14"/>
<TextBlock Text="报告问题" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#27AE60"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="💬" FontSize="14"/>
<TextBlock Text="在线客服" FontSize="14"/>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>

11
Views/Pages/HelpPageView.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace MyAvaloniaApp.Views.Pages;
public partial class HelpPageView : UserControl
{
public HelpPageView()
{
InitializeComponent();
}
}

181
Views/Pages/IconsPageView.axaml

@ -0,0 +1,181 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:vm="using:MyAvaloniaApp.ViewModels.Pages"
xmlns:converters="using:MyAvaloniaApp.Converters"
xmlns:heroicons="clr-namespace:HeroIconsAvalonia.Controls;assembly=HeroIconsAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
x:Class="MyAvaloniaApp.Views.Pages.IconsPageView"
x:DataType="vm:IconsPageViewModel">
<Design.DataContext>
<vm:IconsPageViewModel />
</Design.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 页面标题 -->
<StackPanel Grid.Row="0" Margin="0,0,0,20">
<TextBlock Text="HeroIcons 图标库"
FontSize="24"
FontWeight="Bold"
Foreground="{StaticResource TextPrimary}"/>
<TextBlock Text="浏览和选择 HeroIcons 图标"
FontSize="14"
Foreground="{StaticResource SecondaryGrayDark}"
Margin="0,5,0,0"/>
<!-- HeroIcons.Avalonia 静态示例 -->
<StackPanel Orientation="Horizontal" Margin="0,15,0,0" Spacing="20">
<TextBlock Text="HeroIcons.Avalonia 示例:"
FontSize="14"
FontWeight="SemiBold"
Foreground="{StaticResource TextPrimary}"
VerticalAlignment="Center"/>
<!-- 示例图标 -->
<StackPanel Orientation="Horizontal" Spacing="15">
<!-- Home 图标 -->
<StackPanel Spacing="5">
<Border Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderMedium}"
BorderThickness="1"
CornerRadius="6"
Width="40" Height="40"
HorizontalAlignment="Center">
<heroicons:HeroIcon Foreground="{StaticResource TextPrimary}" Type="Home" Width="20" Height="20"/>
</Border>
<TextBlock Text="Home" FontSize="10"
Foreground="{StaticResource SecondaryGrayDark}"
HorizontalAlignment="Center"/>
</StackPanel>
<!-- User 图标 -->
<StackPanel Spacing="5">
<Border Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderMedium}"
BorderThickness="1"
CornerRadius="6"
Width="40" Height="40"
HorizontalAlignment="Center">
<heroicons:HeroIcon Foreground="{StaticResource TextPrimary}" Type="User" Width="20" Height="20"/>
</Border>
<TextBlock Text="User" FontSize="10"
Foreground="{StaticResource SecondaryGrayDark}"
HorizontalAlignment="Center"/>
</StackPanel>
<!-- Settings 图标 -->
<StackPanel Spacing="5">
<Border Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderMedium}"
BorderThickness="1"
CornerRadius="6"
Width="40" Height="40"
HorizontalAlignment="Center">
<heroicons:HeroIcon Foreground="{StaticResource TextPrimary}" Type="Cog6Tooth" Width="20" Height="20"/>
</Border>
<TextBlock Text="Settings" FontSize="10"
Foreground="{StaticResource SecondaryGrayDark}"
HorizontalAlignment="Center"/>
</StackPanel>
<!-- Heart 图标 -->
<StackPanel Spacing="5">
<Border Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderMedium}"
BorderThickness="1"
CornerRadius="6"
Width="40" Height="40"
HorizontalAlignment="Center">
<heroicons:HeroIcon Foreground="{StaticResource TextPrimary}" Type="Heart" Width="20" Height="20"/>
</Border>
<TextBlock Text="Heart" FontSize="10"
Foreground="{StaticResource SecondaryGrayDark}"
HorizontalAlignment="Center"/>
</StackPanel>
</StackPanel>
</StackPanel>
</StackPanel>
<!-- HeroIcons MVVM 数据绑定网格 -->
<ScrollViewer Grid.Row="1"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemsSource="{Binding HeroIcons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="8" Margin="10"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="{StaticResource BackgroundLight}"
BorderBrush="{StaticResource BorderLight}"
BorderThickness="1"
CornerRadius="8"
Margin="5"
Padding="15">
<Border.Styles>
<Style Selector="Border">
<Setter Property="Background" Value="{StaticResource BackgroundLight}"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderLight}"/>
</Style>
<Style Selector="Border:pointerover">
<Setter Property="Background" Value="{StaticResource BackgroundLightHover}"/>
<Setter Property="BorderBrush" Value="{StaticResource PrimaryBlue}"/>
</Style>
</Border.Styles>
<Button Background="Transparent"
BorderThickness="0"
Command="{Binding $parent[UserControl].DataContext.SelectIconCommand}"
CommandParameter="{Binding}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Button.Styles>
<Style Selector="Button">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="Transparent"/>
</Style>
</Button.Styles>
<StackPanel>
<!-- HeroIcon 控件 -->
<Border Background="{StaticResource BackgroundWhite}"
BorderBrush="{StaticResource BorderMedium}"
BorderThickness="1"
CornerRadius="6"
Width="48" Height="48"
HorizontalAlignment="Center"
Margin="0,0,0,10">
<heroicons:HeroIcon Type="{Binding IconType}"
Kind="{Binding IconKind}"
Width="24" Height="24"
Foreground="{StaticResource TextPrimary}"/>
</Border>
<!-- 图标信息 -->
<TextBlock Text="{Binding DisplayName}"
FontSize="10"
Foreground="{StaticResource SecondaryGrayDark}"
HorizontalAlignment="Center"
TextWrapping="Wrap"
MaxWidth="120"/>
</StackPanel>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>

21
Views/Pages/IconsPageView.axaml.cs

@ -0,0 +1,21 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using MyAvaloniaApp.ViewModels.Pages;
namespace MyAvaloniaApp.Views.Pages;
/// <summary>
/// 图标导航页面的 View
/// </summary>
public partial class IconsPageView : UserControl
{
public IconsPageView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}

417
Views/Pages/ReportsPageView.axaml

@ -0,0 +1,417 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:vm="using:MyAvaloniaApp.ViewModels.Pages"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
x:Class="MyAvaloniaApp.Views.Pages.ReportsPageView"
x:DataType="vm:ReportsPageViewModel">
<Design.DataContext>
<vm:ReportsPageViewModel />
</Design.DataContext>
<Grid>
<!-- 报表内容 -->
<ScrollViewer>
<StackPanel Spacing="20">
<!-- 统计概览 -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 总报表数 -->
<Border Grid.Column="0"
Background="#3498DB"
CornerRadius="10"
Margin="0,0,15,0"
Padding="25">
<StackPanel>
<TextBlock Text="📊"
FontSize="32"
HorizontalAlignment="Center"
Margin="0,0,0,10"/>
<TextBlock Text="{Binding TotalReports}"
FontSize="36"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="总报表数"
FontSize="14"
Foreground="White"
HorizontalAlignment="Center"
Opacity="0.9"/>
</StackPanel>
</Border>
<!-- 月度报表 -->
<Border Grid.Column="1"
Background="#E74C3C"
CornerRadius="10"
Margin="5,0,10,0"
Padding="25">
<StackPanel>
<TextBlock Text="📅"
FontSize="32"
HorizontalAlignment="Center"
Margin="0,0,0,10"/>
<TextBlock Text="{Binding MonthlyReports}"
FontSize="36"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="月度报表"
FontSize="14"
Foreground="White"
HorizontalAlignment="Center"
Opacity="0.9"/>
</StackPanel>
</Border>
<!-- 平均评分 -->
<Border Grid.Column="2"
Background="#27AE60"
CornerRadius="10"
Margin="5,0,0,0"
Padding="25">
<StackPanel>
<TextBlock Text="⭐"
FontSize="32"
HorizontalAlignment="Center"
Margin="0,0,0,10"/>
<TextBlock Text="{Binding AverageScore}"
FontSize="36"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="平均评分"
FontSize="14"
Foreground="White"
HorizontalAlignment="Center"
Opacity="0.9"/>
</StackPanel>
</Border>
</Grid>
<!-- 报表类型 -->
<Border Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1"
Padding="25">
<StackPanel>
<TextBlock Text="📋 报表类型"
FontSize="18"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,20"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧报表类型 -->
<StackPanel Grid.Column="0" Margin="0,0,20,0">
<TextBlock Text="业务报表"
FontSize="16"
FontWeight="SemiBold"
Foreground="#2C3E50"
Margin="0,0,0,15"/>
<StackPanel Spacing="10">
<Button Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="📊" FontSize="14"/>
<TextBlock Text="销售报表" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#27AE60"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="💰" FontSize="14"/>
<TextBlock Text="财务报表" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#E74C3C"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="👥" FontSize="14"/>
<TextBlock Text="用户报表" FontSize="14"/>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
<!-- 右侧报表类型 -->
<StackPanel Grid.Column="1">
<TextBlock Text="系统报表"
FontSize="16"
FontWeight="SemiBold"
Foreground="#2C3E50"
Margin="0,0,0,15"/>
<StackPanel Spacing="10">
<Button Background="#F39C12"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="⚡" FontSize="14"/>
<TextBlock Text="性能报表" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#9B59B6"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="🔒" FontSize="14"/>
<TextBlock Text="安全报表" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#1ABC9C"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10"
HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="📈" FontSize="14"/>
<TextBlock Text="趋势报表" FontSize="14"/>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</Grid>
</StackPanel>
</Border>
<!-- 最近报表 -->
<Border Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1"
Padding="25">
<StackPanel>
<TextBlock Text="📄 最近报表"
FontSize="18"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,20"/>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 表头 -->
<Border Grid.Row="0"
Background="#F8F9FA"
CornerRadius="5"
Padding="15,10"
Margin="0,0,0,10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="报表名称"
FontWeight="Bold"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="1"
Text="创建时间"
FontWeight="Bold"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="2"
Text="状态"
FontWeight="Bold"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="3"
Text="操作"
FontWeight="Bold"
Foreground="#2C3E50"/>
</Grid>
</Border>
<!-- 报表行1 -->
<Border Grid.Row="1"
Background="White"
BorderBrush="#E9ECEF"
BorderThickness="0,0,0,1"
Padding="15,10"
Margin="0,0,0,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="月度销售报表"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="1"
Text="2025-01-10"
Foreground="#6C757D"/>
<TextBlock Grid.Column="2"
Text="已完成"
Foreground="#27AE60"/>
<Button Grid.Column="3"
Content="查看"
Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="3"
Padding="10,5"
FontSize="12"/>
</Grid>
</Border>
<!-- 报表行2 -->
<Border Grid.Row="2"
Background="White"
BorderBrush="#E9ECEF"
BorderThickness="0,0,0,1"
Padding="15,10"
Margin="0,0,0,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="用户活跃度报表"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="1"
Text="2025-01-09"
Foreground="#6C757D"/>
<TextBlock Grid.Column="2"
Text="进行中"
Foreground="#F39C12"/>
<Button Grid.Column="3"
Content="查看"
Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="3"
Padding="10,5"
FontSize="12"/>
</Grid>
</Border>
<!-- 报表行3 -->
<Border Grid.Row="3"
Background="White"
BorderBrush="#E9ECEF"
BorderThickness="0,0,0,1"
Padding="15,10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="系统性能报表"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="1"
Text="2025-01-08"
Foreground="#6C757D"/>
<TextBlock Grid.Column="2"
Text="已完成"
Foreground="#27AE60"/>
<Button Grid.Column="3"
Content="查看"
Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="3"
Padding="10,5"
FontSize="12"/>
</Grid>
</Border>
</Grid>
</StackPanel>
</Border>
<!-- 操作按钮 -->
<StackPanel Orientation="Horizontal"
Spacing="15"
HorizontalAlignment="Center"
Margin="0,20,0,0">
<Button Background="#27AE60"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="📊" FontSize="14"/>
<TextBlock Text="生成新报表" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="📁" FontSize="14"/>
<TextBlock Text="导出报表" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#95A5A6"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="⚙️" FontSize="14"/>
<TextBlock Text="报表设置" FontSize="14"/>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>

11
Views/Pages/ReportsPageView.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace MyAvaloniaApp.Views.Pages;
public partial class ReportsPageView : UserControl
{
public ReportsPageView()
{
InitializeComponent();
}
}

210
Views/Pages/SettingsPageView.axaml

@ -0,0 +1,210 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:vm="using:MyAvaloniaApp.ViewModels.Pages"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
x:Class="MyAvaloniaApp.Views.Pages.SettingsPageView"
x:DataType="vm:SettingsPageViewModel">
<Design.DataContext>
<vm:SettingsPageViewModel />
</Design.DataContext>
<Grid>
<!-- 设置内容 -->
<ScrollViewer>
<StackPanel Spacing="20">
<!-- 外观设置 -->
<Border Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1"
Padding="25">
<StackPanel>
<TextBlock Text="🎨 外观设置"
FontSize="18"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,20"/>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 深色模式 -->
<Grid Grid.Row="0" Margin="0,0,0,15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="深色模式"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"/>
<TextBlock Text="启用深色主题界面"
FontSize="12"
Foreground="#6C757D"
Margin="0,2,0,0"/>
</StackPanel>
<ToggleButton Grid.Column="1"
IsChecked="{Binding DarkMode}"
Width="50" Height="25"/>
</Grid>
<!-- 语言设置 -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="界面语言"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"/>
<TextBlock Text="选择系统界面显示语言"
FontSize="12"
Foreground="#6C757D"
Margin="0,2,0,0"/>
</StackPanel>
<ComboBox Grid.Column="1"
SelectedItem="{Binding Language}"
HorizontalAlignment="Right">
<ComboBoxItem Content="中文 (简体)" Tag="zh-CN"/>
<ComboBoxItem Content="English" Tag="en-US"/>
<ComboBoxItem Content="日本語" Tag="ja-JP"/>
</ComboBox>
</Grid>
</Grid>
</StackPanel>
</Border>
<!-- 通知设置 -->
<Border Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1"
Padding="25">
<StackPanel>
<TextBlock Text="🔔 通知设置"
FontSize="18"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,20"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="系统通知"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"/>
<TextBlock Text="接收系统消息和提醒通知"
FontSize="12"
Foreground="#6C757D"
Margin="0,2,0,0"/>
</StackPanel>
<ToggleButton Grid.Column="1"
IsChecked="{Binding Notifications}"
Width="50" Height="25"/>
</Grid>
</StackPanel>
</Border>
<!-- 性能设置 -->
<Border Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1"
Padding="25">
<StackPanel>
<TextBlock Text="⚡ 性能设置"
FontSize="18"
FontWeight="Bold"
Foreground="#2C3E50"
Margin="0,0,0,20"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="数据刷新间隔"
FontSize="14"
FontWeight="SemiBold"
Foreground="#2C3E50"/>
<TextBlock Text="设置数据自动刷新的时间间隔"
FontSize="12"
Foreground="#6C757D"
Margin="0,2,0,0"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="10">
<Slider Value="{Binding RefreshInterval}"
Minimum="10"
Maximum="300"
Width="120"
VerticalAlignment="Center"/>
<TextBlock Text="{Binding RefreshInterval}"
FontSize="12"
Foreground="#2C3E50"
VerticalAlignment="Center"
Width="30"/>
<TextBlock Text="秒"
FontSize="12"
Foreground="#6C757D"
VerticalAlignment="Center"/>
</StackPanel>
</Grid>
</StackPanel>
</Border>
<!-- 操作按钮 -->
<StackPanel Orientation="Horizontal"
Spacing="15"
HorizontalAlignment="Right"
Margin="0,20,0,0">
<Button Background="#27AE60"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="💾" FontSize="14"/>
<TextBlock Text="保存设置" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#95A5A6"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="🔄" FontSize="14"/>
<TextBlock Text="重置默认" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#E74C3C"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="20,12">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="❌" FontSize="14"/>
<TextBlock Text="取消" FontSize="14"/>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>

11
Views/Pages/SettingsPageView.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace MyAvaloniaApp.Views.Pages;
public partial class SettingsPageView : UserControl
{
public SettingsPageView()
{
InitializeComponent();
}
}

200
Views/Pages/UsersPageView.axaml

@ -0,0 +1,200 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:vm="using:MyAvaloniaApp.ViewModels.Pages"
xmlns:converters="using:MyAvaloniaApp.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
x:Class="MyAvaloniaApp.Views.Pages.UsersPageView"
x:DataType="vm:UsersPageViewModel">
<Design.DataContext>
<vm:UsersPageViewModel />
</Design.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 操作按钮 -->
<StackPanel Grid.Row="0"
Orientation="Horizontal"
Spacing="10"
Margin="0,0,0,20">
<Button Background="#27AE60"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="➕" FontSize="14"/>
<TextBlock Text="添加用户" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="📝" FontSize="14"/>
<TextBlock Text="批量导入" FontSize="14"/>
</StackPanel>
</Button>
<Button Background="#95A5A6"
Foreground="White"
BorderThickness="0"
CornerRadius="5"
Padding="15,10">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="🔄" FontSize="14"/>
<TextBlock Text="刷新列表" FontSize="14"/>
</StackPanel>
</Button>
</StackPanel>
<!-- 用户列表 -->
<Border Grid.Row="1"
Background="White"
CornerRadius="10"
BorderBrush="#DEE2E6"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 表头 -->
<Border Grid.Row="0"
Background="#F8F9FA"
CornerRadius="10,10,0,0"
Padding="20,15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="ID"
FontWeight="Bold"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="1"
Text="姓名"
FontWeight="Bold"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="2"
Text="邮箱"
FontWeight="Bold"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="3"
Text="角色"
FontWeight="Bold"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="4"
Text="状态"
FontWeight="Bold"
Foreground="#2C3E50"/>
<TextBlock Grid.Column="5"
Text="操作"
FontWeight="Bold"
Foreground="#2C3E50"/>
</Grid>
</Border>
<!-- 用户数据 -->
<ListBox Grid.Row="1"
ItemsSource="{Binding Users}"
Background="Transparent"
BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="White"
BorderBrush="#E9ECEF"
BorderThickness="0,0,0,1"
Padding="20,15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding Id}"
Foreground="#6C757D"
VerticalAlignment="Center"/>
<TextBlock Grid.Column="1"
Text="{Binding Name}"
Foreground="#2C3E50"
FontWeight="SemiBold"
VerticalAlignment="Center"/>
<TextBlock Grid.Column="2"
Text="{Binding Email}"
Foreground="#6C757D"
VerticalAlignment="Center"/>
<!-- 角色标签 -->
<Border Grid.Column="3"
Background="{Binding Role, Converter={x:Static converters:StringConverters.RoleToColorConverter}}"
CornerRadius="12"
Padding="8,4"
HorizontalAlignment="Left">
<TextBlock Text="{Binding Role}"
Foreground="White"
FontSize="12"
FontWeight="SemiBold"/>
</Border>
<!-- 状态标签 -->
<Border Grid.Column="4"
Background="{Binding Status, Converter={x:Static converters:StringConverters.StatusToColorConverter}}"
CornerRadius="12"
Padding="8,4"
HorizontalAlignment="Left">
<TextBlock Text="{Binding Status}"
Foreground="White"
FontSize="12"
FontWeight="SemiBold"/>
</Border>
<!-- 操作按钮 -->
<StackPanel Grid.Column="5"
Orientation="Horizontal"
Spacing="5">
<Button Width="30" Height="30"
Background="#3498DB"
Foreground="White"
BorderThickness="0"
CornerRadius="15"
ToolTip.Tip="编辑">
<TextBlock Text="✏️" FontSize="12"/>
</Button>
<Button Width="30" Height="30"
Background="#E74C3C"
Foreground="White"
BorderThickness="0"
CornerRadius="15"
ToolTip.Tip="删除">
<TextBlock Text="🗑️" FontSize="12"/>
</Button>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</Grid>
</UserControl>

11
Views/Pages/UsersPageView.axaml.cs

@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace MyAvaloniaApp.Views.Pages;
public partial class UsersPageView : UserControl
{
public UsersPageView()
{
InitializeComponent();
}
}

230
WSL部署说明.md

@ -0,0 +1,230 @@
# Avalonia应用WSL Ubuntu部署说明
## 📋 概述
本文档说明如何将Avalonia应用发布到WSL Ubuntu环境中运行。
## 🚀 发布步骤
### 1. 生成Linux版本
在Windows PowerShell中运行以下命令之一:
**方法1: 使用批处理脚本**
```cmd
publish-linux.bat
```
**方法2: 使用PowerShell脚本**
```powershell
.\publish-linux.ps1
```
**方法3: 手动发布**
```cmd
dotnet publish -c Release -r linux-x64 --self-contained true -o "publish\linux-x64"
```
### 2. 拷贝到WSL Ubuntu
#### 方法1: 通过Windows文件系统访问
1. 在WSL Ubuntu中,Windows驱动器挂载在 `/mnt/`
2. 创建目标目录:
```bash
mkdir -p ~/MyAvaloniaApp
```
3. 拷贝文件:
```bash
cp -r /mnt/d/Log/MyAvaloniaApp/publish/linux-x64/* ~/MyAvaloniaApp/
```
#### 方法2: 通过WSL文件系统
1. 在Windows中,WSL文件系统位于:`\\wsl$\Ubuntu\home\<username>\`
2. 直接将 `publish\linux-x64\` 文件夹复制到WSL用户目录
### 3. 在Ubuntu中设置权限和运行
1. 进入应用目录:
```bash
cd ~/MyAvaloniaApp
```
2. 设置执行权限:
```bash
chmod +x MyAvaloniaApp
```
3. 运行应用:
```bash
./MyAvaloniaApp
```
## 🔧 系统要求
### Ubuntu系统要求
- Ubuntu 18.04 或更高版本
- 图形界面支持(X11或Wayland)
- X11相关系统库(**必须安装**)
### 自动安装依赖
**推荐方法**: 使用提供的安装脚本
在Windows中运行:
```cmd
install-wsl-deps.bat
```
或在WSL Ubuntu中手动运行:
```bash
# 拷贝脚本到WSL
cp /mnt/d/Log/MyAvaloniaApp/install-ubuntu-deps.sh ~/
chmod +x ~/install-ubuntu-deps.sh
./install-ubuntu-deps.sh
```
### 字体依赖安装
**重要**: 为了解决字体渲染问题,需要安装字体包:
```bash
# 安装常用字体包
sudo apt update
sudo apt install -y \
fonts-dejavu-core \
fonts-liberation \
fonts-liberation2 \
fontconfig \
fonts-noto-core \
fonts-noto-cjk
```
### 手动安装依赖
如果自动安装失败,可以手动安装:
```bash
sudo apt update
sudo apt install -y \
libice6 libsm6 libx11-6 libx11-xcb1 libxcb1 \
libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \
libxcb-randr0 libxcb-render-util0 libxcb-render0 \
libxcb-shape0 libxcb-sync1 libxcb-util1 \
libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 \
libxkbcommon-x11-0 libxkbcommon0 \
libgl1-mesa-glx libgl1-mesa-dri libglib2.0-0 \
libgthread-2.0-0 libgtk-3-0 libcairo-gobject2 \
libgdk-pixbuf2.0-0 libpango-1.0-0 libpangocairo-1.0-0 \
libatk1.0-0 libcairo2 libpixman-1-0 libxcomposite1 \
libxcursor1 libxdamage1 libxext6 libxfixes3 \
libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
fonts-dejavu-core fonts-liberation fontconfig \
libasound2 libatspi2.0-0 libdrm2 libxau6 libxdmcp6
```
### 图形界面支持
如果遇到图形界面问题,可能需要安装:
```bash
# 对于X11
sudo apt install x11-apps
# 对于Wayland
sudo apt install wayland-protocols
```
## 🐛 常见问题
### 1. libICE.so.6 缺失错误
**错误信息**: `System.DllNotFoundException: Unable to load shared library 'libICE.so.6'`
**解决方案**:
```bash
# 运行依赖安装脚本
./install-ubuntu-deps.sh
# 或手动安装X11库
sudo apt install libice6 libsm6 libx11-6
```
### 2. 权限问题
如果遇到权限错误:
```bash
chmod +x MyAvaloniaApp
```
### 3. 图形界面问题
如果应用无法显示窗口:
```bash
# 检查DISPLAY环境变量
echo $DISPLAY
# 设置DISPLAY(如果需要)
export DISPLAY=:0
# 如果使用WSLg,确保Windows版本支持
# 如果使用X11服务器,确保VcXsrv或Xming正在运行
```
### 4. 依赖库问题
如果缺少其他依赖库:
```bash
# 检查缺失的依赖
ldd MyAvaloniaApp
# 安装缺失的库
sudo apt install <missing-library-name>
```
### 5. 字体渲染问题
**问题**: 应用界面显示为占位符条状图标,文本无法正常显示
**解决方案**:
```bash
# 安装字体包
sudo apt install -y fonts-dejavu-core fonts-liberation fontconfig
# 刷新字体缓存
sudo fc-cache -fv
# 检查字体是否安装成功
fc-list | grep -i dejavu
```
**验证字体安装**:
```bash
# 查看可用字体
fc-list : family
# 测试字体渲染
echo "测试字体渲染" | xargs -I {} bash -c 'echo {} | figlet -f standard'
```
### 6. WSL图形界面设置
**方法1: 使用WSLg (Windows 11)**
- 确保Windows版本支持WSLg
- 无需额外配置
**方法2: 使用X11服务器**
- 安装VcXsrv或Xming
- 在WSL中设置: `export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0`
## 📁 文件结构
发布后的文件结构:
```
publish/linux-x64/
├── MyAvaloniaApp # 主执行文件
├── MyAvaloniaApp.dll # 应用程序集
├── MyAvaloniaApp.pdb # 调试符号
├── Avalonia.*.dll # Avalonia框架文件
├── System.*.dll # .NET运行时文件
├── lib*.so # 本地库文件
└── ... # 其他依赖文件
```
## 🔄 更新应用
当需要更新应用时:
1. 重新运行发布脚本
2. 停止旧版本应用
3. 替换文件
4. 重新运行
## 📝 注意事项
- 发布文件包含完整的.NET运行时,文件较大
- 确保WSL Ubuntu有足够的磁盘空间
- 首次运行可能需要较长时间来加载所有依赖
- 建议在发布前测试应用功能

18
app.manifest

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embedded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.0.0.0" name="MyAvaloniaApp.Desktop"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
</assembly>

27
appsettings.json

@ -0,0 +1,27 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"MyAvaloniaApp": "Debug"
},
"Console": {
"IncludeScopes": true,
"TimestampFormat": "yyyy-MM-dd HH:mm:ss "
}
},
"AppSettings": {
"ApplicationName": "My Avalonia App",
"Version": "1.0.0",
"Environment": "Development",
"Features": {
"EnableLogging": true,
"EnableMetrics": false,
"EnableTelemetry": false
}
},
"ConnectionStrings": {
"DefaultConnection": "Data Source=app.db"
}
}

BIN
bin/Debug/net8.0/Avalonia.Base.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Controls.ColorPicker.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Controls.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.DesignerSupport.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Desktop.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Diagnostics.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Dialogs.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Fonts.Inter.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.FreeDesktop.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Markup.Xaml.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Markup.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Metal.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.MicroCom.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Native.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.OpenGL.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.ReactiveUI.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Remote.Protocol.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Skia.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Themes.Fluent.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Themes.Simple.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Vulkan.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Win32.Automation.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.Win32.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.X11.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Avalonia.dll

Binary file not shown.

BIN
bin/Debug/net8.0/DynamicData.dll

Binary file not shown.

BIN
bin/Debug/net8.0/HarfBuzzSharp.dll

Binary file not shown.

BIN
bin/Debug/net8.0/MicroCom.Runtime.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Configuration.Abstractions.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Configuration.Binder.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Configuration.CommandLine.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Configuration.EnvironmentVariables.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Configuration.FileExtensions.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Configuration.Json.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Configuration.UserSecrets.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Configuration.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.DependencyInjection.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Diagnostics.Abstractions.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Diagnostics.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.FileProviders.Abstractions.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.FileProviders.Physical.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.FileSystemGlobbing.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Hosting.Abstractions.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Hosting.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Logging.Abstractions.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Logging.Configuration.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Logging.Console.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Logging.Debug.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Logging.EventLog.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Logging.EventSource.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Logging.dll

Binary file not shown.

BIN
bin/Debug/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll

Binary file not shown.

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save