diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml b/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml
index 106b3e35b..500e8e67e 100644
--- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml
@@ -2,20 +2,23 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:System.Application.UI"
x:Class="System.Application.UI.App">
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
@@ -29,12 +28,43 @@
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/About/About_OpenSourcePage.axaml b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/About/About_OpenSourcePage.axaml
new file mode 100644
index 000000000..16fccc462
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/About/About_OpenSourcePage.axaml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/About/About_OpenSourcePage.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/About/About_OpenSourcePage.axaml.cs
new file mode 100644
index 000000000..082aa0a5e
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/About/About_OpenSourcePage.axaml.cs
@@ -0,0 +1,19 @@
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using System.Application.UI.ViewModels;
+
+namespace System.Application.UI.Views.Pages
+{
+ public class About_OpenSourcePage : UserControl
+ {
+ public About_OpenSourcePage()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/AboutPage.axaml b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/AboutPage.axaml
new file mode 100644
index 000000000..4f88b59a0
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/AboutPage.axaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/AboutPage.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/AboutPage.axaml.cs
new file mode 100644
index 000000000..3de829b00
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/AboutPage.axaml.cs
@@ -0,0 +1,19 @@
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using System.Application.UI.ViewModels;
+
+namespace System.Application.UI.Views.Pages
+{
+ public class AboutPage : UserControl
+ {
+ public AboutPage()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/DebugPage.axaml b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/DebugPage.axaml
new file mode 100644
index 000000000..d8be1c724
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/DebugPage.axaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/DebugPage.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/DebugPage.axaml.cs
new file mode 100644
index 000000000..94891a1c2
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/DebugPage.axaml.cs
@@ -0,0 +1,19 @@
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using System.Application.UI.ViewModels;
+
+namespace System.Application.UI.Views.Pages
+{
+ public class DebugPage : UserControl
+ {
+ public DebugPage()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/StartPage.axaml b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/StartPage.axaml
new file mode 100644
index 000000000..f04904149
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/StartPage.axaml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/StartPage.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/StartPage.axaml.cs
new file mode 100644
index 000000000..4204ca89c
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Pages/StartPage.axaml.cs
@@ -0,0 +1,19 @@
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using System.Application.UI.ViewModels;
+
+namespace System.Application.UI.Views.Pages
+{
+ public class StartPage : UserControl
+ {
+ public StartPage()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/System.Application.SteamTools.Client.Desktop.Avalonia.csproj b/System.Application.SteamTools.Client.Desktop.Avalonia/System.Application.SteamTools.Client.Desktop.Avalonia.csproj
index f118b97c9..f70d3f0b6 100644
--- a/System.Application.SteamTools.Client.Desktop.Avalonia/System.Application.SteamTools.Client.Desktop.Avalonia.csproj
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/System.Application.SteamTools.Client.Desktop.Avalonia.csproj
@@ -61,9 +61,21 @@
+
+ About_OpenSourcePage.axaml
+
+
+ AboutPage.axaml
+
GameListPage.axaml
+
+ DebugPage.axaml
+
+
+ StartPage.axaml
+
SteamAccountPage.axaml
diff --git a/System.Application.SteamTools.Client.Desktop/Extensions/ViewModelExtensions.cs b/System.Application.SteamTools.Client.Desktop/Extensions/ViewModelExtensions.cs
new file mode 100644
index 000000000..6db13e749
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/Extensions/ViewModelExtensions.cs
@@ -0,0 +1,22 @@
+using System.Application.UI.ViewModels;
+
+namespace System.Application
+{
+ public static class ViewModelExtensions
+ {
+ ///
+ /// 将对象添加到 的中
+ ///
+ public static T AddTo(this T disposable, ViewModelBase vm) where T : IDisposable
+ {
+ if (vm == null)
+ {
+ disposable.Dispose();
+ return disposable;
+ }
+
+ vm.CompositeDisposable.Add(disposable);
+ return disposable;
+ }
+ }
+}
diff --git a/System.Application.SteamTools.Client.Desktop/System.Application.SteamTools.Client.Desktop.csproj b/System.Application.SteamTools.Client.Desktop/System.Application.SteamTools.Client.Desktop.csproj
index 1a9e4c660..d15be75d7 100644
--- a/System.Application.SteamTools.Client.Desktop/System.Application.SteamTools.Client.Desktop.csproj
+++ b/System.Application.SteamTools.Client.Desktop/System.Application.SteamTools.Client.Desktop.csproj
@@ -61,6 +61,12 @@
+
+
+ PreserveNewest
+
+
+
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/ItemViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/ItemViewModel.cs
new file mode 100644
index 000000000..b3f1a9d60
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/ItemViewModel.cs
@@ -0,0 +1,31 @@
+using ReactiveUI;
+
+namespace System.Application.UI.ViewModels
+{
+ public class ItemViewModel : ViewModelBase
+ {
+ #region IsSelected 変更通知
+
+ private bool _IsSelected;
+
+ public virtual bool IsSelected
+ {
+ get => _IsSelected;
+ set => this.RaiseAndSetIfChanged(ref _IsSelected, value);
+ }
+
+ #endregion
+
+ #region IsShowTab 変更通知
+
+ private bool _IsShowTab = true;
+
+ public virtual bool IsShowTab
+ {
+ get => _IsShowTab;
+ set => this.RaiseAndSetIfChanged(ref _IsShowTab, value);
+ }
+
+ #endregion
+ }
+}
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/TabItemViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/TabItemViewModel.cs
new file mode 100644
index 000000000..436ad82eb
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/TabItemViewModel.cs
@@ -0,0 +1,59 @@
+using ReactiveUI;
+using StatefulModel.EventListeners;
+using System.Application.UI.Resx;
+using System.Threading.Tasks;
+
+namespace System.Application.UI.ViewModels
+{
+ public abstract class TabItemViewModel : ItemViewModel
+ {
+ #region Name 変更通知
+
+ public abstract string Name { get; protected set; }
+
+ #endregion
+
+ #region Badge 変更通知
+
+ private int? _Badge;
+
+ public virtual int? Badge
+ {
+ get => _Badge;
+ protected set => this.RaiseAndSetIfChanged(ref _Badge, value);
+ }
+
+ #endregion
+
+ #region Status 変更通知
+
+ private ViewModelBase? _Status;
+
+ ///
+ /// 获取状态栏中显示的状态
+ ///
+ public virtual ViewModelBase? Status
+ {
+ get => _Status;
+ protected set => this.RaiseAndSetIfChanged(ref _Status, value);
+ }
+
+ #endregion
+
+ protected TabItemViewModel()
+ {
+ if (IsInDesignMode) return;
+
+ this.CompositeDisposable?.Add(new PropertyChangedEventListener(R.Current)
+ {
+ (sender, args) => this.RaisePropertyChanged(nameof(this.Name)),
+ });
+ }
+
+
+ internal async virtual Task Initialize()
+ {
+ await Task.CompletedTask;
+ }
+ }
+}
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/ViewModelBase.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/ViewModelBase.cs
index 372e04b2c..f74f5a32e 100644
--- a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/ViewModelBase.cs
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/ViewModelBase.cs
@@ -5,7 +5,18 @@ namespace System.Application.UI.ViewModels
{
public class ViewModelBase : ReactiveObject, IDisposable
{
- [NonSerialized] CompositeDisposable? _compositeDisposable;
+ [NonSerialized] private CompositeDisposable? _compositeDisposable = new CompositeDisposable();
+ public CompositeDisposable? CompositeDisposable
+ {
+ get => _compositeDisposable;
+ set
+ {
+ if (_compositeDisposable != value)
+ {
+ _compositeDisposable = value;
+ }
+ }
+ }
[NonSerialized] bool _disposed;
@@ -14,6 +25,7 @@ namespace System.Application.UI.ViewModels
///
public static bool IsInDesignMode { get; set; }
+
///
/// 释放该实例使用的所有资源
///
@@ -26,7 +38,7 @@ namespace System.Application.UI.ViewModels
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
- if (disposing) _compositeDisposable?.Dispose();
+ if (disposing) CompositeDisposable?.Dispose();
_disposed = true;
}
}
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/WindowViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/WindowViewModel.cs
index 91526b803..fed8ec87a 100644
--- a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/WindowViewModel.cs
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Base/WindowViewModel.cs
@@ -11,5 +11,10 @@ namespace System.Application.UI.ViewModels
get => title;
set => this.RaiseAndSetIfChanged(ref title, value);
}
+
+ protected void InvokeOnUIDispatcher(Action action)
+ {
+ MainThreadDesktop.BeginInvokeOnMainThread(action);
+ }
}
}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/MainWindowViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/MainWindowViewModel.cs
index 4d3ddb2f1..c46195daf 100644
--- a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/MainWindowViewModel.cs
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/MainWindowViewModel.cs
@@ -9,20 +9,55 @@ namespace System.Application.UI.ViewModels
{
public class MainWindowViewModel : WindowViewModel
{
- bool mTopmost;
+ #region 更改通知
+ bool mTopmost;
public bool Topmost
{
get => mTopmost;
set => this.RaiseAndSetIfChanged(ref mTopmost, value);
}
- public SettingsPageViewModel SettingsPage { get; }
+
+ private TabItemViewModel _SelectedItem;
+ public TabItemViewModel SelectedItem
+ {
+ get => _SelectedItem;
+ set => this.RaiseAndSetIfChanged(ref _SelectedItem, value);
+ }
+
+ #endregion
+
+ public StartPageViewModel StartPage { get; }
+ public GameListPageViewModel GameListPage { get; }
+ public SteamAccountPageViewModel SteamAccountPage { get; }
+
+
+ public IList TabItems { get; set; }
+
public MainWindowViewModel() : base()
{
Title = ThisAssembly.AssemblyTrademark;
- SettingsPage = new SettingsPageViewModel();
+
+ this.TabItems = new List
+ {
+ (this.StartPage = new StartPageViewModel().AddTo(this)),
+ (this.SteamAccountPage = new SteamAccountPageViewModel().AddTo(this)),
+ (this.GameListPage = new GameListPageViewModel().AddTo(this)),
+
+
+
+ #region SystemTab
+ SettingsPageViewModel.Instance,
+ AboutPageViewModel.Instance,
+#if DEBUG
+ new DebugPageViewModel().AddTo(this),
+#endif
+ #endregion
+ };
+
+ this.SelectedItem = this.TabItems.First();
}
}
}
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/AboutPageViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/AboutPageViewModel.cs
new file mode 100644
index 000000000..d28240b7b
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/AboutPageViewModel.cs
@@ -0,0 +1,16 @@
+using System.Application.UI.Resx;
+
+namespace System.Application.UI.ViewModels
+{
+ public class AboutPageViewModel : TabItemViewModel
+ {
+ public static AboutPageViewModel Instance { get; } = new AboutPageViewModel();
+
+ public override string Name
+ {
+ get => AppResources.About;
+ protected set { throw new NotImplementedException(); }
+ }
+
+ }
+}
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.cs
new file mode 100644
index 000000000..547bbf47f
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.cs
@@ -0,0 +1,33 @@
+using ReactiveUI;
+using System.Application.UI.Resx;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Application.UI.ViewModels
+{
+ public class DebugPageViewModel : TabItemViewModel
+ {
+ public override string Name
+ {
+ get => "Debug";
+ protected set { throw new NotImplementedException(); }
+ }
+
+ private string _DebugString = string.Empty;
+ public string DebugString
+ {
+ get => _DebugString;
+ protected set => this.RaiseAndSetIfChanged(ref _DebugString, value);
+ }
+
+ public DebugPageViewModel()
+ {
+
+ }
+
+ public void DebugButton_Click()
+ {
+ DebugString += "Test Command" + Environment.NewLine;
+ }
+ }
+}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.cs
new file mode 100644
index 000000000..f4844436a
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.cs
@@ -0,0 +1,14 @@
+using System.Application.UI.Resx;
+
+namespace System.Application.UI.ViewModels
+{
+ public class GameListPageViewModel : TabItemViewModel
+ {
+ public override string Name
+ {
+ get => AppResources.GameList;
+ protected set { throw new NotImplementedException(); }
+ }
+
+ }
+}
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Settings/SettingsPageViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs
similarity index 85%
rename from System.Application.SteamTools.Client.Desktop/UI/ViewModels/Settings/SettingsPageViewModel.cs
rename to System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs
index d178893f4..de24f7ebb 100644
--- a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Settings/SettingsPageViewModel.cs
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs
@@ -5,8 +5,16 @@ using System.Linq;
namespace System.Application.UI.ViewModels
{
- public class SettingsPageViewModel : ViewModelBase
+ public class SettingsPageViewModel : TabItemViewModel
{
+ public static SettingsPageViewModel Instance { get; } = new SettingsPageViewModel();
+
+ public override string Name
+ {
+ get => AppResources.Settings;
+ protected set { throw new NotImplementedException(); }
+ }
+
public SettingsPageViewModel()
{
//Languages = R.Languages.Select(Convert).ToList();
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.cs
new file mode 100644
index 000000000..e3e992d12
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.cs
@@ -0,0 +1,14 @@
+using System.Application.UI.Resx;
+
+namespace System.Application.UI.ViewModels
+{
+ public class StartPageViewModel : TabItemViewModel
+ {
+ public override string Name
+ {
+ get => AppResources.Welcome;
+ protected set { throw new NotImplementedException(); }
+ }
+
+ }
+}
diff --git a/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.cs b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.cs
new file mode 100644
index 000000000..c993e56b6
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.cs
@@ -0,0 +1,14 @@
+using System.Application.UI.Resx;
+
+namespace System.Application.UI.ViewModels
+{
+ public class SteamAccountPageViewModel : TabItemViewModel
+ {
+ public override string Name
+ {
+ get => AppResources.UserFastChange;
+ protected set { throw new NotImplementedException(); }
+ }
+
+ }
+}