diff --git a/WonderLab/App.axaml b/WonderLab/App.axaml
index 464d9fb8..55857f92 100644
--- a/WonderLab/App.axaml
+++ b/WonderLab/App.axaml
@@ -22,6 +22,7 @@
+
diff --git a/WonderLab/Classes/Datas/TaskData/PreLaunchCheckTask.cs b/WonderLab/Classes/Datas/TaskData/PreLaunchCheckTask.cs
index dac539cb..6c4ea5ff 100644
--- a/WonderLab/Classes/Datas/TaskData/PreLaunchCheckTask.cs
+++ b/WonderLab/Classes/Datas/TaskData/PreLaunchCheckTask.cs
@@ -21,6 +21,7 @@
using WonderLab.ViewModels.Dialogs.Setting;
using CommunityToolkit.Mvvm.Messaging;
using WonderLab.Classes.Datas.MessageData;
+using Avalonia.Threading;
namespace WonderLab.Classes.Datas.TaskData;
@@ -78,6 +79,8 @@ public PreLaunchCheckTask(
public override async ValueTask BuildWorkItemAsync(CancellationToken token) {
try {
_isReturnTrue = true;
+
+ var res = Dispatcher.UIThread.CheckAccess();
await Task.Run(CheckJavaAndExecuteAsync, token);
await Task.Run(CheckResourcesAndExecuteAsync, token);
await Task.Run(CheckAccountAndExecuteAsync, token);
@@ -132,8 +135,8 @@ async Task CheckResourcesAndExecuteAsync() {
: null;
var resultComplete = await _resourceChecker.MissingResources.DownloadResourceEntrysAsync(downloadSource, args => {
- var percentage = args.ToPercentage() * 100;
- ReportProgress(percentage, $"{args.CompletedCount}/{args.TotalCount} - {percentage:0.00}%");
+ //var percentage = args.ToPercentage() * 100;
+ //(percentage, $"{args.CompletedCount}/{args.TotalCount} - {percentage:0.00}%");
}, _downloadService.MainDownloadRequest);
if (!resultComplete) {
diff --git a/WonderLab/Classes/Datas/TaskData/TaskBase.cs b/WonderLab/Classes/Datas/TaskData/TaskBase.cs
index 4c764829..d5d4fb2e 100644
--- a/WonderLab/Classes/Datas/TaskData/TaskBase.cs
+++ b/WonderLab/Classes/Datas/TaskData/TaskBase.cs
@@ -107,16 +107,16 @@ protected void DebounceUIUpdate() {
ProgressDetail = _insideProgressDetail;
}
- protected void ReportProgress(string detail) {
- Dispatcher.UIThread.Post(() => {
+ protected async void ReportProgress(string detail) {
+ await Dispatcher.UIThread.InvokeAsync(() => {
if (!string.IsNullOrEmpty(detail)) {
ProgressDetail = detail;
}
});
}
- protected void ReportProgress(double progress) {
- Dispatcher.UIThread.Post(() => {
+ protected async void ReportProgress(double progress) {
+ await Dispatcher.UIThread.InvokeAsync(() => {
if (progress < 0.0) {
IsIndeterminate = true;
}
diff --git a/WonderLab/Services/QueuedHostedService.cs b/WonderLab/Services/QueuedHostedService.cs
index 62a637ed..fc7194f7 100644
--- a/WonderLab/Services/QueuedHostedService.cs
+++ b/WonderLab/Services/QueuedHostedService.cs
@@ -33,8 +33,7 @@ public override Task StartAsync(CancellationToken cancellationToken) {
}
protected override Task ExecuteAsync(CancellationToken stoppingToken) {
- return Task.WhenAll(ProcessTaskQueueAsync(stoppingToken), ProcessTaskQueueAsync(stoppingToken),
- ProcessTaskQueueAsync(stoppingToken));
+ return ProcessTaskQueueAsync(stoppingToken);
}
private async Task ProcessTaskQueueAsync(CancellationToken stoppingToken) {
diff --git a/WonderLab/Services/TaskService.cs b/WonderLab/Services/TaskService.cs
index 329e3381..c51b6cb5 100644
--- a/WonderLab/Services/TaskService.cs
+++ b/WonderLab/Services/TaskService.cs
@@ -55,7 +55,7 @@ public BackgroundTaskQueue(int queueLength) {
public async ValueTask QueueBackgroundWorkItemAsync(ITaskJob job) {
if (job == null) {
- throw new ArgumentNullException(nameof(job));
+ ArgumentNullException.ThrowIfNull(job);
}
await _queue.Writer.WriteAsync(job);
diff --git a/WonderLab/Services/UI/DialogService.cs b/WonderLab/Services/UI/DialogService.cs
index f3f6dd28..bab7aaa3 100644
--- a/WonderLab/Services/UI/DialogService.cs
+++ b/WonderLab/Services/UI/DialogService.cs
@@ -101,7 +101,7 @@ public async void ShowContentDialog(object parameter) where TViewMod
var viewName = typeof(TViewModel).Name.Replace("ViewModel", "");
if (_dialogs.TryGetValue(viewName, out var contentFunc)) {
- _dispatcher.Post(async () => {
+ await _dispatcher.InvokeAsync(async () => {
var dialogObject = contentFunc() as UserControl;
dialogObject!.DataContext = App.ServiceProvider!.GetRequiredService();
(dialogObject.DataContext as DialogViewModelBase).Initialize(parameter);
diff --git a/WonderLab/Services/UI/WindowService.cs b/WonderLab/Services/UI/WindowService.cs
index 264b2385..393b77a3 100644
--- a/WonderLab/Services/UI/WindowService.cs
+++ b/WonderLab/Services/UI/WindowService.cs
@@ -58,7 +58,7 @@ public static void ChangeToOobe() {
}
public void Close() {
- if (_wrapService.Client is { IsConnected:true }) {
+ if (_wrapService.Client is { IsConnected: true }) {
_wrapService.Close();
}
@@ -105,9 +105,9 @@ public async void SetBackground(int type) {
if (string.IsNullOrEmpty(path)) {
_dialogService = App.ServiceProvider.GetService();
- var result = await _dialogService.OpenFilePickerAsync([
+ var result = await Task.Run(async () => await _dialogService.OpenFilePickerAsync([
new FilePickerFileType("图像文件") { Patterns = new List() { "*.png", "*.jpg", "*.jpeg", "*.tif", "*.tiff" } }
- ], "打开文件");
+ ], "打开文件"));
if (result is null) {
return;
diff --git a/WonderLab/ViewModels/Pages/HomePageViewModel.cs b/WonderLab/ViewModels/Pages/HomePageViewModel.cs
index a40ce8b4..6476177b 100644
--- a/WonderLab/ViewModels/Pages/HomePageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/HomePageViewModel.cs
@@ -42,7 +42,7 @@ public HomePageViewModel(
GameEntries = _gameService.GameEntries.ToObservableList();
- _ = Task.Run(async () => {
+ RunBackgroundWork(async() => {
await Task.Delay(250);
ActiveGameEntry = _gameService.ActiveGameEntry;
});
@@ -66,7 +66,7 @@ private void Launch() {
var preCheckTask = new PreLaunchCheckTask(App.GetService(),
_gameService,
- App.GetService(),
+ App.GetService(),
_settingService, App.GetService(),
App.GetService(),
_notificationService,
diff --git a/WonderLab/ViewModels/Pages/MultiplayerPageViewModel.cs b/WonderLab/ViewModels/Pages/MultiplayerPageViewModel.cs
index 3a5f5514..bbbe5fff 100644
--- a/WonderLab/ViewModels/Pages/MultiplayerPageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/MultiplayerPageViewModel.cs
@@ -61,7 +61,7 @@ public MultiplayerPageViewModel(
_timeOutSpan = TimeSpan.FromSeconds(10);
MinecraftPort = "25565";
- _ = InitializeAsync();
+ Initialize();
}
[RelayCommand]
@@ -79,12 +79,12 @@ private void CopyToken() {
_windowService.CopyText(UserToken);
}
- private async ValueTask InitializeAsync() {
+ private void Initialize() {
_wrapService.NewRequest += OnNewRequest;
_wrapService.LoginedSuccessfully += OnLoginedSuccessfully;
_wrapService.ConnectPeerSuccessfully += OnConnectPeerSuccessfully;
- await Task.Run(async () => {
+ RunBackgroundWork(async () => {
try {
_upnPService.Init();
_upnPService.Search();
diff --git a/WonderLab/ViewModels/Pages/Navigation/DownloadNavigationPageViewModel.cs b/WonderLab/ViewModels/Pages/Navigation/DownloadNavigationPageViewModel.cs
index 2d04fdb3..a553b9d1 100644
--- a/WonderLab/ViewModels/Pages/Navigation/DownloadNavigationPageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/Navigation/DownloadNavigationPageViewModel.cs
@@ -9,7 +9,7 @@
namespace WonderLab.ViewModels.Pages.Navigation;
public sealed partial class DownloadNavigationPageViewModel : ViewModelBase {
- private readonly INavigationService _navigationService;
+ private readonly DownloadNavigationService _navigationService;
[ObservableProperty] private NavigationPageData _activePage;
@@ -19,7 +19,7 @@ await dispatcher.InvokeAsync(() => {
if (ActivePage?.PageKey != p.PageKey) {
ActivePage = p;
}
- });
+ }, DispatcherPriority.ApplicationIdle);
};
_navigationService = navigationService;
diff --git a/WonderLab/ViewModels/Pages/Navigation/SettingNavigationPageViewModel.cs b/WonderLab/ViewModels/Pages/Navigation/SettingNavigationPageViewModel.cs
index 6745422f..02a9de6a 100644
--- a/WonderLab/ViewModels/Pages/Navigation/SettingNavigationPageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/Navigation/SettingNavigationPageViewModel.cs
@@ -9,7 +9,7 @@
namespace WonderLab.ViewModels.Pages.Navigation;
public sealed partial class SettingNavigationPageViewModel : ViewModelBase {
- private readonly INavigationService _navigationService;
+ private readonly SettingNavigationService _navigationService;
[ObservableProperty] private object _activeItem;
[ObservableProperty] private NavigationPageData _activePage;
diff --git a/WonderLab/ViewModels/Pages/Setting/AboutPageViewModel.cs b/WonderLab/ViewModels/Pages/Setting/AboutPageViewModel.cs
index 22a74073..a227d166 100644
--- a/WonderLab/ViewModels/Pages/Setting/AboutPageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/Setting/AboutPageViewModel.cs
@@ -7,9 +7,11 @@ namespace WonderLab.ViewModels.Pages.Setting;
public sealed partial class AboutPageViewModel : ViewModelBase {
[RelayCommand]
private void JumpToLink(string url) {
- using var process = Process.Start(new ProcessStartInfo(url) {
- UseShellExecute = true,
- Verb = "open"
+ RunBackgroundWork(() => {
+ using var _ = Process.Start(new ProcessStartInfo(url) {
+ UseShellExecute = true,
+ Verb = "open"
+ });
});
}
}
\ No newline at end of file
diff --git a/WonderLab/ViewModels/Pages/Setting/AccountSettingPageViewModel.cs b/WonderLab/ViewModels/Pages/Setting/AccountSettingPageViewModel.cs
index 6dc33c89..bacfd787 100644
--- a/WonderLab/ViewModels/Pages/Setting/AccountSettingPageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/Setting/AccountSettingPageViewModel.cs
@@ -24,7 +24,7 @@ public sealed partial class AccountSettingPageViewModel : ViewModelBase {
public AccountSettingPageViewModel(
DialogService dialogService,
- SettingService settingService,
+ SettingService settingService,
NotificationService notificationService,
TaskService taskService) {
_dialogService = dialogService;
@@ -32,7 +32,7 @@ public AccountSettingPageViewModel(
_notificationService = notificationService;
if (_settingService.Data.Accounts.Count != 0) {
- taskService.QueueJob(new AccountLoadTask(_settingService.Data.Accounts));
+ RunBackgroundWork(() => taskService.QueueJob(new AccountLoadTask(_settingService.Data.Accounts)));
}
WeakReferenceMessenger.Default.Register(this, AccountHandle);
@@ -49,8 +49,8 @@ partial void OnActiveAccountChanged(AccountViewData value) {
_settingService.Data.ActiveAccount = value?.Account;
}
- private async void AccountHandle(object obj, AccountMessage accountMessage) {
- await Task.Run(async () => {
+ private void AccountHandle(object obj, AccountMessage accountMessage) {
+ RunBackgroundWork(async () => {
foreach (var item in accountMessage.Accounts.Select(x => new AccountViewData(x))) {
Accounts.Add(item);
await Task.Delay(5);
@@ -58,11 +58,13 @@ await Task.Run(async () => {
});
}
- private async void AccountViewHandle(object obj, AccountViewMessage accountMessage) {
- foreach (var item in accountMessage.Accounts) {
- Accounts.Add(item);
- await Task.Delay(5);
- }
+ private void AccountViewHandle(object obj, AccountViewMessage accountMessage) {
+ RunBackgroundWork(async () => {
+ foreach (var item in accountMessage.Accounts) {
+ Accounts.Add(item);
+ await Task.Delay(5);
+ }
+ });
}
private void AccountChangeHandle(object obj, AccountChangeNotificationMessage accountMessage) {
diff --git a/WonderLab/ViewModels/Pages/Setting/DetailSettingPageViewModel.cs b/WonderLab/ViewModels/Pages/Setting/DetailSettingPageViewModel.cs
index cb417d84..372b7332 100644
--- a/WonderLab/ViewModels/Pages/Setting/DetailSettingPageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/Setting/DetailSettingPageViewModel.cs
@@ -80,6 +80,7 @@ private void Search() {
private void PressOobe() {
_dialogService.ShowContentDialog();
}
+
protected override void OnPropertyChanged(PropertyChangedEventArgs e) {
base.OnPropertyChanged(e);
diff --git a/WonderLab/ViewModels/Pages/Setting/LaunchSettingPageViewModel.cs b/WonderLab/ViewModels/Pages/Setting/LaunchSettingPageViewModel.cs
index b1b0b121..48c90cfd 100644
--- a/WonderLab/ViewModels/Pages/Setting/LaunchSettingPageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/Setting/LaunchSettingPageViewModel.cs
@@ -25,7 +25,7 @@ public sealed partial class LaunchSettingPageViewModel : ViewModelBase {
private readonly JavaFetcher _javaFetcher;
private readonly DialogService _dialogService;
private readonly SettingService _settingService;
- private readonly ILogger _logger;
+ private readonly ILogger _logger;
[ObservableProperty] private string _maxMemory;
[ObservableProperty] private string _activeGameFolder;
@@ -42,8 +42,8 @@ public sealed partial class LaunchSettingPageViewModel : ViewModelBase {
public LaunchSettingPageViewModel(
JavaFetcher javaFetcher,
- DialogService dialogService,
- SettingService settingService,
+ DialogService dialogService,
+ SettingService settingService,
ILogger logger) {
_dialogService = dialogService;
_settingService = settingService;
@@ -65,33 +65,33 @@ public LaunchSettingPageViewModel(
}
[RelayCommand]
- private async Task Search(string key) {
- if (key is "Folder") {
- var folder = await _dialogService.OpenFolderPickerAsync("Select Folder");
- if (folder is null) {
- return;
- }
+ private void Search(string key) {
+ RunBackgroundWork(async () => {
+ if (key is "Folder") {
+ var folder = await _dialogService.OpenFolderPickerAsync("Select Folder");
+ if (folder is null) {
+ return;
+ }
- if (GameFolders.Any(x => x == folder.FullName)) {
- return;
- }
+ if (GameFolders.Any(x => x == folder.FullName)) {
+ return;
+ }
- GameFolders = GameFolders.Union(Enumerable.Repeat(folder.FullName, 1)).ToObservableList();
- ActiveGameFolder = GameFolders.Last();
- } else {
- var java = await _dialogService.OpenFilePickerAsync(new List {
+ GameFolders = GameFolders.Union(Enumerable.Repeat(folder.FullName, 1)).ToObservableList();
+ ActiveGameFolder = GameFolders.Last();
+ } else {
+ var java = await _dialogService.OpenFilePickerAsync(new List {
new("Java文件") { Patterns = [EnvironmentUtil.IsWindow ? "javaw.exe" : "java"] }
}, "Select Java");
- if (java is null) {
- return;
- }
+ if (java is null) {
+ return;
+ }
- RunBackgroundWork(() => {
- string javaPath = java.Name is "jre.bundle"
+ string javaPath = java.Name is "jre.bundle"
? Path.Combine(java.FullName, "Contents", "Home", "bin", "java")
: java.FullName;
-
+
var javaInfo = JavaUtil.GetJavaInfo(javaPath);
if (Javas.Count > 0 && Javas.Any(x => x?.JavaPath == javaInfo.JavaPath)) {
return;
@@ -99,8 +99,8 @@ private async Task Search(string key) {
Javas = Javas.Union(Enumerable.Repeat(javaInfo, 1)).ToObservableList();
ActiveJava = Javas.Last();
- });
- }
+ }
+ });
}
[RelayCommand]
@@ -118,16 +118,17 @@ private void Remove(string key) {
}
[RelayCommand]
- private async Task AutoSearch() {
- var javas = await _javaFetcher.FetchAsync();
- Javas ??= [];
- Javas.Clear();
+ private void AutoSearch() {
+ RunBackgroundWork(async () => {
+ var javas = await _javaFetcher.FetchAsync();
+ Javas ??= [];
+ Javas.Clear();
- var javasList = Javas?.Union(javas);
- Javas = javasList.ToObservableList();
+ var javasList = Javas?.Union(javas);
+ Javas = javasList.ToObservableList();
- ActiveJava = Javas.LastOrDefault();
- _logger.LogInformation("共存在 {JavaCount} 个 Java", Javas.Count);
+ ActiveJava = Javas.LastOrDefault();
+ }, () => _logger.LogInformation("共存在 {JavaCount} 个 Java", Javas.Count));
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e) {
diff --git a/WonderLab/ViewModels/Pages/Setting/NetworkSettingPageViewModel.cs b/WonderLab/ViewModels/Pages/Setting/NetworkSettingPageViewModel.cs
index a8a84800..850860cc 100644
--- a/WonderLab/ViewModels/Pages/Setting/NetworkSettingPageViewModel.cs
+++ b/WonderLab/ViewModels/Pages/Setting/NetworkSettingPageViewModel.cs
@@ -9,11 +9,11 @@ public sealed partial class NetworkSettingPageViewModel : ViewModelBase {
private readonly SettingService _settingService;
private readonly DownloadService _downloadService;
- [ObservableProperty] private bool _isUseMirrorDownloadSource;
-
[ObservableProperty] private int _multiPartsCount;
[ObservableProperty] private int _multiThreadsCount;
+ [ObservableProperty] private bool _isUseMirrorDownloadSource;
+
public NetworkSettingPageViewModel(SettingService settingService, DownloadService downloadService) {
_settingService = settingService;
_downloadService = downloadService;
diff --git a/WonderLab/ViewModels/Windows/MainWindowViewModel.cs b/WonderLab/ViewModels/Windows/MainWindowViewModel.cs
index 70ca705d..9b590b7c 100644
--- a/WonderLab/ViewModels/Windows/MainWindowViewModel.cs
+++ b/WonderLab/ViewModels/Windows/MainWindowViewModel.cs
@@ -22,12 +22,9 @@ public sealed partial class MainWindowViewModel : ViewModelBase {
private readonly SettingService _settingService;
private readonly DialogService _dialogService;
private readonly TaskService _taskService;
- private readonly INavigationService _navigationService;
+ private readonly HostNavigationService _navigationService;
private readonly NotificationService _notificationService;
- private readonly Timer _timer = new(TimeSpan.FromSeconds(1));
- [ObservableProperty] private string _time;
- [ObservableProperty] private string _year;
[ObservableProperty] private string _imagePath;
[ObservableProperty] private int _blurRadius;
@@ -48,25 +45,20 @@ public MainWindowViewModel(
DialogService dialogService,
SettingService settingService,
HostNavigationService navigationService,
- NotificationService notificationService,
- Dispatcher dispatcher) {
+ NotificationService notificationService) {
_taskService = taskService;
_dialogService = dialogService;
_settingService = settingService;
_navigationService = navigationService;
_notificationService = notificationService;
- _navigationService.NavigationRequest += async p => {
- await dispatcher.InvokeAsync(async () => {
- if (ActivePanelPage?.PageKey != p.PageKey) {
- if (p.PageKey is "HomePage") {
- ActivePage = p.Page;
- } else {
- ActivePanelPage = null;
- ActivePanelPage = p;
- }
- }
- }, DispatcherPriority.Background);
+ _navigationService.NavigationRequest += p => {
+ if (p.PageKey is "HomePage") {
+ ActivePage = p.Page;
+ } else {
+ ActivePanelPage = null;
+ ActivePanelPage = p;
+ }
};
WeakReferenceMessenger.Default.Register(this, BlurEnableValueHandle);
@@ -128,14 +120,6 @@ private void ParallaxModeChangeHandle(object obj, ParallaxModeChangeMessage para
public void OnLoaded() {
_taskService.QueueJob(new InitTask(_settingService, _dialogService, _notificationService));
- Time = DateTime.Now.ToString("t");
- Year = DateTime.Now.ToString("d");
-
- _timer.Elapsed += (_, args) => {
- Time = args.SignalTime.ToString("t");
- Year = args.SignalTime.ToString("d");
- };
-
Tasks = new(_taskService.TaskJobs);
Notifications = new(_notificationService.Notifications);
@@ -147,6 +131,5 @@ public void OnLoaded() {
};
_navigationService.NavigationTo();
- _timer.Start();
}
}
\ No newline at end of file
diff --git a/WonderLab/Views/Controls/ImageCard.cs b/WonderLab/Views/Controls/ImageCard.cs
new file mode 100644
index 00000000..ce7fba9f
--- /dev/null
+++ b/WonderLab/Views/Controls/ImageCard.cs
@@ -0,0 +1,42 @@
+using Avalonia;
+using Avalonia.Media;
+using Avalonia.Metadata;
+using System.Windows.Input;
+using Avalonia.Controls.Primitives;
+
+namespace WonderLab.Views.Controls;
+
+public sealed class ImageCard : TemplatedControl {
+ public static readonly StyledProperty SourceProperty =
+ AvaloniaProperty.Register(nameof(Source));
+
+ public static readonly StyledProperty TitleProperty =
+ AvaloniaProperty.Register(nameof(Source));
+
+ public static readonly StyledProperty DescriptionProperty =
+ AvaloniaProperty.Register(nameof(Source));
+
+ public static readonly StyledProperty CommandProperty =
+ AvaloniaProperty.Register(nameof(Command));
+
+ [Content]
+ public IImage Source {
+ get => GetValue(SourceProperty);
+ set => SetValue(SourceProperty, value);
+ }
+
+ public string Title {
+ get => GetValue(TitleProperty);
+ set => SetValue(TitleProperty, value);
+ }
+
+ public string Description {
+ get => GetValue(DescriptionProperty);
+ set => SetValue(DescriptionProperty, value);
+ }
+
+ public ICommand Command {
+ get => GetValue(CommandProperty);
+ set => SetValue(CommandProperty, value);
+ }
+}
\ No newline at end of file
diff --git a/WonderLab/Views/Controls/NavigationView.cs b/WonderLab/Views/Controls/NavigationView.cs
index 3b65d83b..2c5af9b9 100644
--- a/WonderLab/Views/Controls/NavigationView.cs
+++ b/WonderLab/Views/Controls/NavigationView.cs
@@ -1,22 +1,17 @@
-using Avalonia;
-using Avalonia.Controls;
-using System.Collections;
-using System.Windows.Input;
-using Avalonia.Collections;
-using WonderLab.Services.UI;
-using Avalonia.Interactivity;
-using Avalonia.Controls.Primitives;
-using Avalonia.Media.Transformation;
-using Microsoft.Extensions.DependencyInjection;
+using System;
+using Avalonia;
using Avalonia.Input;
-using System;
+using Avalonia.Controls;
+using Avalonia.Metadata;
using Avalonia.Threading;
+using System.Windows.Input;
using System.Threading.Tasks;
-using System.Threading;
using Avalonia.Controls.Metadata;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
+using Avalonia.Controls.Primitives;
+using Avalonia.Animation;
+using Avalonia.Animation.Easings;
+using Avalonia.Styling;
+using Avalonia.Media.Transformation;
namespace WonderLab.Views.Controls;
@@ -38,6 +33,8 @@ public double ActualPx {
private Frame PART_Frame;
private Frame PART_PanelFrame;
+ private LayoutTransformControl PART_LayoutTransformControl;
+
private Border _backgroundPanel;
private bool _oldIsOpenBackgroundPanel;
@@ -54,7 +51,8 @@ public double ActualPx {
public static readonly StyledProperty IsOpenBackgroundPanelProperty =
AvaloniaProperty.Register(nameof(IsOpenBackgroundPanel));
-
+
+ [Content]
public object Content {
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
@@ -75,47 +73,51 @@ public bool IsOpenBackgroundPanel {
set => SetValue(IsOpenBackgroundPanelProperty, value);
}
- private void UpdateIndicator() {
- TemplateSettings.ActualPx = _backgroundPanel.Bounds.Height + 15;
- }
+ private DispatcherOperation RunAnimation() {
+ var px = IsOpenBackgroundPanel ? 0 : _backgroundPanel.Bounds.Height + 15;
- private void UpdatePseudoClasses() {
- PseudoClasses.Set(":ispanelopen", IsOpenBackgroundPanel);
- PseudoClasses.Set(":ispanelclose", !IsOpenBackgroundPanel);
- }
+ Dispatcher.UIThread.VerifyAccess();
+ return Dispatcher.UIThread.InvokeAsync(() => {
+ PART_LayoutTransformControl.Opacity = IsOpenBackgroundPanel ? 1 : 0;
+ PART_LayoutTransformControl.RenderTransform = TransformOperations.Parse($"translateY({px}px)");
+ });
- private void OnPanelPropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e) {
- if (e.Property == BoundsProperty) {
- UpdateIndicator();
- }
}
- protected override void OnApplyTemplate(TemplateAppliedEventArgs e) {
+ protected override async void OnApplyTemplate(TemplateAppliedEventArgs e) {
base.OnApplyTemplate(e);
//Layouts
PART_Frame = e.NameScope.Find("PART_Frame");
PART_PanelFrame = e.NameScope.Find("PART_PanelFrame");
+ PART_LayoutTransformControl = e.NameScope.Find("PART_LayoutTransformControl");
_backgroundPanel = e.NameScope.Find("BackgroundPanel");
- _backgroundPanel.PropertyChanged += OnPanelPropertyChanged;
+ await Dispatcher.UIThread.InvokeAsync(() => {
+ PART_LayoutTransformControl.Opacity = 0;
+ PART_LayoutTransformControl.RenderTransform = TransformOperations.Parse($"translateY({_backgroundPanel.Bounds.Height + 15}px)");
+ });
}
protected override async void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) {
base.OnPropertyChanged(change);
if (change.Property == IsOpenBackgroundPanelProperty) {
- UpdatePseudoClasses();
- _oldIsOpenBackgroundPanel = change.GetOldValue();
+ await RunAnimation();
+
+ await Task.Delay(TimeSpan.Parse("0:0:0.3"));
+ await Dispatcher.UIThread.InvokeAsync(() => PART_PanelFrame.Content = PanelContent, DispatcherPriority.ApplicationIdle);
}
if (change.Property == PanelContentProperty) {
- if (!_oldIsOpenBackgroundPanel) {
- _oldIsOpenBackgroundPanel = true;
- await Task.Delay(TimeSpan.Parse("0:0:0.4"));
- }
+ var dispatcherOperation = RunAnimation();
+
+ dispatcherOperation.Completed += async (_, _) => {
+ await Task.Delay(TimeSpan.Parse("0:0:0.3"));
+ await Dispatcher.UIThread.InvokeAsync(() => PART_PanelFrame.Content = PanelContent, DispatcherPriority.ApplicationIdle);
+ };
- await Dispatcher.UIThread.InvokeAsync(() => PART_PanelFrame.Content = PanelContent);
+ await dispatcherOperation;
}
}
}
diff --git a/WonderLab/Views/Controls/Themes/ColorTheme.axaml b/WonderLab/Views/Controls/Themes/ColorTheme.axaml
index 5129a174..f703aeb3 100644
--- a/WonderLab/Views/Controls/Themes/ColorTheme.axaml
+++ b/WonderLab/Views/Controls/Themes/ColorTheme.axaml
@@ -189,6 +189,7 @@
+
@@ -382,6 +383,7 @@
+
diff --git a/WonderLab/Views/Controls/Themes/Controls/ButtonTheme.axaml b/WonderLab/Views/Controls/Themes/Controls/ButtonTheme.axaml
index bbea6246..a13fa934 100644
--- a/WonderLab/Views/Controls/Themes/Controls/ButtonTheme.axaml
+++ b/WonderLab/Views/Controls/Themes/Controls/ButtonTheme.axaml
@@ -2,14 +2,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:WonderLab.Views.Controls">
-
@@ -31,16 +29,20 @@
Easing="ExponentialEaseInOut"/>
+ Property="BorderBrush"
+ Easing="ExponentialEaseOut"/>
+ Property="Foreground"
+ Easing="ExponentialEaseInOut"/>
+ Property="Opacity"
+ Easing="ExponentialEaseOut"/>
+
+
@@ -87,7 +89,7 @@
-
+
+
+
+
+
+
+
+
diff --git a/WonderLab/Views/Controls/Themes/Controls/ImageCardTheme.axaml b/WonderLab/Views/Controls/Themes/Controls/ImageCardTheme.axaml
new file mode 100644
index 00000000..bc8fda30
--- /dev/null
+++ b/WonderLab/Views/Controls/Themes/Controls/ImageCardTheme.axaml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WonderLab/Views/Controls/Themes/Controls/NavigationViewTheme.axaml b/WonderLab/Views/Controls/Themes/Controls/NavigationViewTheme.axaml
index 9d1627a8..44b50138 100644
--- a/WonderLab/Views/Controls/Themes/Controls/NavigationViewTheme.axaml
+++ b/WonderLab/Views/Controls/Themes/Controls/NavigationViewTheme.axaml
@@ -37,6 +37,17 @@
+
+
+
+
+
+
+
-
@@ -85,7 +94,7 @@
-
+ -->
-
-
-
-
-
\ No newline at end of file
diff --git a/WonderLab/Views/Controls/Themes/Controls/PopupRootTheme.axaml b/WonderLab/Views/Controls/Themes/Controls/PopupRootTheme.axaml
index 65e81dbf..f7d6996d 100644
--- a/WonderLab/Views/Controls/Themes/Controls/PopupRootTheme.axaml
+++ b/WonderLab/Views/Controls/Themes/Controls/PopupRootTheme.axaml
@@ -8,7 +8,7 @@
diff --git a/WonderLab/Views/Controls/Themes/Controls/ProgressBarTheme.axaml b/WonderLab/Views/Controls/Themes/Controls/ProgressBarTheme.axaml
index de2d1cda..a308502e 100644
--- a/WonderLab/Views/Controls/Themes/Controls/ProgressBarTheme.axaml
+++ b/WonderLab/Views/Controls/Themes/Controls/ProgressBarTheme.axaml
@@ -55,12 +55,12 @@
CornerRadius="{TemplateBinding CornerRadius}">
-
+ Duration="0:0:0.6" />-->
diff --git a/WonderLab/Views/Pages/Download/SearchPage.axaml b/WonderLab/Views/Pages/Download/SearchPage.axaml
index 66156be7..f0236fe6 100644
--- a/WonderLab/Views/Pages/Download/SearchPage.axaml
+++ b/WonderLab/Views/Pages/Download/SearchPage.axaml
@@ -6,7 +6,8 @@
xmlns:controls="clr-namespace:WonderLab.Views.Controls"
x:Class="WonderLab.Views.Download.SearchPage">
-
@@ -20,8 +21,28 @@
-
+ ColumnDefinitions="0.6*, 12, 1*">
+
+
+
+
+
+
+
diff --git a/WonderLab/Views/Pages/Navigation/DownloadNavigationPage.axaml b/WonderLab/Views/Pages/Navigation/DownloadNavigationPage.axaml
index e7d8e25d..137e812a 100644
--- a/WonderLab/Views/Pages/Navigation/DownloadNavigationPage.axaml
+++ b/WonderLab/Views/Pages/Navigation/DownloadNavigationPage.axaml
@@ -25,21 +25,19 @@
IsSelected="True"
Classes="sidebaritem"
Content="搜索"
- Foreground="{DynamicResource SecondaryBrush600}"/>
+ Foreground="{DynamicResource SuccessBaseColor}"/>
+ Foreground="{DynamicResource SuccessBaseColor}"/>
+ Foreground="{DynamicResource SuccessBaseColor}"/>
diff --git a/WonderLab/Views/Windows/MainWindow.axaml b/WonderLab/Views/Windows/MainWindow.axaml
index 9f039aba..88a5b838 100644
--- a/WonderLab/Views/Windows/MainWindow.axaml
+++ b/WonderLab/Views/Windows/MainWindow.axaml
@@ -98,13 +98,16 @@
+ TextAlignment="Right">
+
+
+
+