Add a menu for changing themes

This commit is contained in:
Manuel Thalmann 2024-06-07 00:12:52 +02:00
parent b00dfc6f5b
commit 41dd2b0f64
18 changed files with 205 additions and 8 deletions

View file

@ -4,12 +4,12 @@
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TodoDetails"
Shell.FlyoutBehavior="Disabled"
Title="TodoDetails">
<ShellContent
Title="Home"
xmlns:view="clr-namespace:TodoDetails.View"
Shell.FlyoutBehavior="Flyout">
<ShellContent Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
<ShellContent Title="Settings"
ContentTemplate="{DataTemplate view:SettingsPage}"
Route="SettingsPage"/>
</Shell>

View file

@ -24,6 +24,8 @@ namespace TodoDetails
builder.Services.AddSingleton<TodoService>();
builder.Services.AddSingleton<TodosViewModel>();
builder.Services.AddSingleton<MainPage>();
builder.Services.AddSingleton<SettingsViewModel>();
builder.Services.AddSingleton<SettingsPage>();
builder.Services.AddTransient<TodoDetailsViewModel>();
builder.Services.AddTransient<TodoDetailsPage>();

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TodoDetails.Resources.Styles.ThemeStyles">
</ResourceDictionary>

View file

@ -0,0 +1,9 @@
namespace TodoDetails.Resources.Styles;
public partial class ThemeStyles : ResourceDictionary
{
public ThemeStyles()
{
InitializeComponent();
}
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TodoDetails.Resources.Themes.BasicTheme">
</ResourceDictionary>

View file

@ -0,0 +1,9 @@
namespace TodoDetails.Resources.Themes;
public partial class BasicTheme : ResourceDictionary
{
public BasicTheme()
{
InitializeComponent();
}
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TodoDetails.Resources.Themes.Dark">
</ResourceDictionary>

View file

@ -0,0 +1,9 @@
namespace TodoDetails.Resources.Themes;
public partial class Dark : ResourceDictionary
{
public Dark()
{
InitializeComponent();
}
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TodoDetails.Resources.Themes.Earth">
</ResourceDictionary>

View file

@ -0,0 +1,9 @@
namespace TodoDetails.Resources.Themes;
public partial class Earth : ResourceDictionary
{
public Earth()
{
InitializeComponent();
}
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TodoDetails.Resources.Themes.Light">
</ResourceDictionary>

View file

@ -0,0 +1,9 @@
namespace TodoDetails.Resources.Themes;
public partial class Light : ResourceDictionary
{
public Light()
{
InitializeComponent();
}
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TodoDetails.Resources.Themes.Pink">
</ResourceDictionary>

View file

@ -0,0 +1,9 @@
namespace TodoDetails.Resources.Themes;
public partial class Pink : ResourceDictionary
{
public Pink()
{
InitializeComponent();
}
}

View file

@ -68,6 +68,27 @@
</ItemGroup>
<ItemGroup>
<MauiXaml Update="Resources\Styles\ThemeStyles.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Resources\Themes\BasicTheme.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Resources\Themes\Dark.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Resources\Themes\Earth.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Resources\Themes\Light.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Resources\Themes\Pink.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="View\SettingsPage.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="View\TodoDetailsPage.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodel="clr-namespace:TodoDetails.ViewModel"
x:Class="TodoDetails.View.SettingsPage"
x:DataType="viewmodel:SettingsViewModel"
Title="SettingsPage">
<Border>
<VerticalStackLayout Padding="5">
<Picker x:Name="ThemePicker"
Title="Pick a Theme"
SelectedIndexChanged="SelectedThemeChanged"
ItemsSource="{Binding Themes}"/>
</VerticalStackLayout>
</Border>
</ContentPage>

View file

@ -0,0 +1,22 @@
using TodoDetails.ViewModel;
namespace TodoDetails.View;
public partial class SettingsPage : ContentPage
{
public SettingsPage(SettingsViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
}
private void SelectedThemeChanged(object sender, EventArgs e)
{
var selectedItem = (string)ThemePicker.SelectedItem;
if (selectedItem != null)
{
(BindingContext as SettingsViewModel)?.LoadNewTheme(selectedItem);
}
}
}

View file

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TodoDetails.Resources.Styles;
using TodoDetails.Resources.Themes;
namespace TodoDetails.ViewModel
{
public class SettingsViewModel
{
private Dictionary<string, ResourceDictionary> defaultThemes = new()
{
{ "Light", new Light() },
{ "Dark", new Dark() },
{ "Earth", new Earth() },
{ "Pink", new Pink() }
};
public SettingsViewModel()
{
Themes = defaultThemes.Select(x => x.Key).ToList();
}
public List<string> Themes { get; set; }
public void LoadNewTheme(string themeName)
{
if (!MainThread.IsMainThread)
{
MainThread.BeginInvokeOnMainThread(() => LoadNewTheme(themeName));
return;
}
ResourceDictionary dictionary = defaultThemes[themeName];
if (dictionary != null)
{
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(new ThemeStyles());
Application.Current.Resources.MergedDictionaries.Add(dictionary);
}
}
}
}