Refactored initialization
This commit is contained in:
Родитель
e61ca81ddf
Коммит
1fc0f0f465
23
README.md
23
README.md
|
@ -16,9 +16,9 @@ Theme manager for [Avalonia](https://github.com/AvaloniaUI/Avalonia) application
|
|||
|
||||
Theme manager searches user provided themes directory for `*.xaml` theme files otherwise built-in `Light` and `Dark` theme are used.
|
||||
|
||||
The `ThemeSelector` static `Instance` property neeeds to be initalized before using `ThemeSelector` class.
|
||||
The `ThemeSelector` is created and initalized by calling static `Create` method.
|
||||
|
||||
The `ThemeSelector` uses `Styles[0]` property of `Windows` to insert selected theme `Style`.
|
||||
The `ThemeSelector` uses `Styles[0]` property of `Window` to insert selected theme `Style`.
|
||||
|
||||
`App.xaml`
|
||||
```XAML
|
||||
|
@ -44,6 +44,8 @@ namespace AvaloniaApp
|
|||
{
|
||||
public class App : Application
|
||||
{
|
||||
public static IThemeSelector Selector;
|
||||
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
@ -52,12 +54,12 @@ namespace AvaloniaApp
|
|||
|
||||
static void AppMain(Application app, string[] args)
|
||||
{
|
||||
ThemeSelector.Instance = new ThemeSelector("Themes");
|
||||
ThemeSelector.Instance.LoadSelectedTheme("AvaloniaApp.theme");
|
||||
Selector = ThemeSelector.Create("Themes");
|
||||
Selector.LoadSelectedTheme("AvaloniaApp.theme");
|
||||
|
||||
app.Run(new MainWindow());
|
||||
|
||||
ThemeSelector.Instance.SaveSelectedTheme("AvaloniaApp.theme");
|
||||
Selector.SaveSelectedTheme("AvaloniaApp.theme");
|
||||
}
|
||||
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
|
@ -79,16 +81,17 @@ namespace AvaloniaApp
|
|||
<Window x:Class="AvaloniaApp.MainWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:Themes="clr-namespace:Avalonia.ThemeManager;assembly=Avalonia.ThemeManager"
|
||||
xmlns:app="clr-namespace:AvaloniaApp;assembly=AvaloniaApp"
|
||||
xmlns:manager="clr-namespace:Avalonia.ThemeManager;assembly=Avalonia.ThemeManager"
|
||||
Title="AvaloniaApp" Width="800" Height="600"
|
||||
Foreground="{DynamicResource ThemeForegroundBrush}">
|
||||
<Window.Resources>
|
||||
<Themes:ObjectEqualityMultiConverter x:Key="ObjectEqualityMultiConverter"/>
|
||||
<manager:ObjectEqualityMultiConverter x:Key="ObjectEqualityMultiConverter"/>
|
||||
</Window.Resources>
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Menu Grid.Row="0">
|
||||
<MenuItem Header="_View">
|
||||
<MenuItem Header="_Theme" DataContext="{x:Static Themes:ThemeSelector.Instance}" Items="{Binding Themes}">
|
||||
<MenuItem Header="_Theme" DataContext="{x:Static app:App.Selector}" Items="{Binding Themes}">
|
||||
<MenuItem.Styles>
|
||||
<Style Selector="MenuItem">
|
||||
<Setter Property="Header" Value="{Binding Name}"/>
|
||||
|
@ -130,7 +133,7 @@ namespace AvaloniaApp
|
|||
{
|
||||
this.InitializeComponent();
|
||||
this.AttachDevTools();
|
||||
ThemeSelector.Instance.EnableThemes(this);
|
||||
App.Selector.EnableThemes(this);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
|
@ -141,7 +144,7 @@ namespace AvaloniaApp
|
|||
}
|
||||
```
|
||||
|
||||
The `ThemeSelector.Instance.EnableThemes(this);` can be used in multiple windows.
|
||||
The `EnableThemes(...);` can be used to enable themes for multiple windows.
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ namespace AvaloniaApp
|
|||
{
|
||||
public class App : Application
|
||||
{
|
||||
public static IThemeSelector Selector;
|
||||
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
@ -16,12 +18,12 @@ namespace AvaloniaApp
|
|||
|
||||
static void AppMain(Application app, string[] args)
|
||||
{
|
||||
ThemeSelector.Instance = new ThemeSelector("Themes");
|
||||
ThemeSelector.Instance.LoadSelectedTheme("AvaloniaApp.theme");
|
||||
Selector = ThemeSelector.Create("Themes");
|
||||
Selector.LoadSelectedTheme("AvaloniaApp.theme");
|
||||
|
||||
app.Run(new MainWindow());
|
||||
|
||||
ThemeSelector.Instance.SaveSelectedTheme("AvaloniaApp.theme");
|
||||
Selector.SaveSelectedTheme("AvaloniaApp.theme");
|
||||
}
|
||||
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
<Window x:Class="AvaloniaApp.MainWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:Themes="clr-namespace:Avalonia.ThemeManager;assembly=Avalonia.ThemeManager"
|
||||
xmlns:app="clr-namespace:AvaloniaApp;assembly=AvaloniaApp"
|
||||
xmlns:manager="clr-namespace:Avalonia.ThemeManager;assembly=Avalonia.ThemeManager"
|
||||
Title="AvaloniaApp" Width="800" Height="600"
|
||||
Foreground="{DynamicResource ThemeForegroundBrush}">
|
||||
<Window.Resources>
|
||||
<Themes:ObjectEqualityMultiConverter x:Key="ObjectEqualityMultiConverter"/>
|
||||
<manager:ObjectEqualityMultiConverter x:Key="ObjectEqualityMultiConverter"/>
|
||||
</Window.Resources>
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Menu Grid.Row="0">
|
||||
<MenuItem Header="_View">
|
||||
<MenuItem Header="_Theme" DataContext="{x:Static Themes:ThemeSelector.Instance}" Items="{Binding Themes}">
|
||||
<MenuItem Header="_Theme" DataContext="{x:Static app:App.Selector}" Items="{Binding Themes}">
|
||||
<MenuItem.Styles>
|
||||
<Style Selector="MenuItem">
|
||||
<Setter Property="Header" Value="{Binding Name}"/>
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace AvaloniaApp
|
|||
{
|
||||
this.InitializeComponent();
|
||||
this.AttachDevTools();
|
||||
ThemeSelector.Instance.EnableThemes(this);
|
||||
App.Selector.EnableThemes(this);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) Wiesław Šoltés. All rights reserved.
|
||||
// Copyright (c) Wiesław Šoltés. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
@ -13,11 +13,11 @@ using ReactiveUI;
|
|||
|
||||
namespace Avalonia.ThemeManager
|
||||
{
|
||||
public class Theme : ReactiveObject
|
||||
public class Theme : ReactiveObject, ITheme
|
||||
{
|
||||
private string _name;
|
||||
private IStyle _style;
|
||||
private ThemeSelector _selector;
|
||||
private IThemeSelector _selector;
|
||||
|
||||
public string Name
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ namespace Avalonia.ThemeManager
|
|||
set => this.RaiseAndSetIfChanged(ref _style, value);
|
||||
}
|
||||
|
||||
public ThemeSelector Selector
|
||||
public IThemeSelector Selector
|
||||
{
|
||||
get => _selector;
|
||||
set => this.RaiseAndSetIfChanged(ref _selector, value);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Wiesław Šoltés. All rights reserved.
|
||||
// Copyright (c) Wiesław Šoltés. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
@ -13,37 +14,48 @@ using ReactiveUI;
|
|||
|
||||
namespace Avalonia.ThemeManager
|
||||
{
|
||||
public class ThemeSelector : ReactiveObject
|
||||
public sealed class ThemeSelector : ReactiveObject, IThemeSelector
|
||||
{
|
||||
public static ThemeSelector Instance;
|
||||
|
||||
private Theme _selectedTheme;
|
||||
private ObservableCollection<Theme> _themes;
|
||||
private ObservableCollection<Window> _windows;
|
||||
private ITheme _selectedTheme;
|
||||
private IList<ITheme> _themes;
|
||||
private IList<Window> _windows;
|
||||
|
||||
public Theme SelectedTheme
|
||||
public ITheme SelectedTheme
|
||||
{
|
||||
get => _selectedTheme;
|
||||
set => this.RaiseAndSetIfChanged(ref _selectedTheme, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<Theme> Themes
|
||||
public IList<ITheme> Themes
|
||||
{
|
||||
get => _themes;
|
||||
set => this.RaiseAndSetIfChanged(ref _themes, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<Window> Windows
|
||||
public IList<Window> Windows
|
||||
{
|
||||
get => _windows;
|
||||
set => this.RaiseAndSetIfChanged(ref _windows, value);
|
||||
}
|
||||
|
||||
public ThemeSelector(string path)
|
||||
private ThemeSelector()
|
||||
{
|
||||
_themes = new ObservableCollection<Theme>();
|
||||
}
|
||||
|
||||
try
|
||||
public static IThemeSelector Create(string path)
|
||||
{
|
||||
return new ThemeSelector()
|
||||
{
|
||||
Themes = new ObservableCollection<ITheme>(),
|
||||
Windows = new ObservableCollection<Window>()
|
||||
}.LoadThemes(path);
|
||||
}
|
||||
|
||||
private IThemeSelector LoadThemes(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (string file in System.IO.Directory.EnumerateFiles(path, "*.xaml"))
|
||||
{
|
||||
|
@ -64,10 +76,10 @@ namespace Avalonia.ThemeManager
|
|||
|
||||
_selectedTheme = _themes.FirstOrDefault();
|
||||
|
||||
_windows = new ObservableCollection<Window>();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Theme LoadTheme(string file)
|
||||
public ITheme LoadTheme(string file)
|
||||
{
|
||||
var name = System.IO.Path.GetFileNameWithoutExtension(file);
|
||||
var xaml = System.IO.File.ReadAllText(file);
|
||||
|
@ -97,7 +109,7 @@ namespace Avalonia.ThemeManager
|
|||
};
|
||||
}
|
||||
|
||||
public void ApplyTheme(Theme theme)
|
||||
public void ApplyTheme(ITheme theme)
|
||||
{
|
||||
if (theme != null)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче