diff --git a/src/AKSoftware.Localization.MultiLanguages.UWP/AKSoftware.Localization.MultiLanguages.UWP.csproj b/src/AKSoftware.Localization.MultiLanguages.UWP/AKSoftware.Localization.MultiLanguages.UWP.csproj
index cb4dd92..dd7e848 100644
--- a/src/AKSoftware.Localization.MultiLanguages.UWP/AKSoftware.Localization.MultiLanguages.UWP.csproj
+++ b/src/AKSoftware.Localization.MultiLanguages.UWP/AKSoftware.Localization.MultiLanguages.UWP.csproj
@@ -11,7 +11,7 @@
AKSoftware.Localization.MultiLanguages.UWP
en-US
UAP
- 10.0.18362.0
+ 10.0.19041.0
10.0.17134.0
14
512
diff --git a/src/AKSoftware.Localization.MultiLanguages.WPF/AKSoftware.Localization.MultiLanguages.WPF.csproj b/src/AKSoftware.Localization.MultiLanguages.WPF/AKSoftware.Localization.MultiLanguages.WPF.csproj
new file mode 100644
index 0000000..b396fb2
--- /dev/null
+++ b/src/AKSoftware.Localization.MultiLanguages.WPF/AKSoftware.Localization.MultiLanguages.WPF.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/src/AKSoftware.Localization.MultiLanguages.WPF/WpfLanguageContainer.cs b/src/AKSoftware.Localization.MultiLanguages.WPF/WpfLanguageContainer.cs
new file mode 100644
index 0000000..e16f38a
--- /dev/null
+++ b/src/AKSoftware.Localization.MultiLanguages.WPF/WpfLanguageContainer.cs
@@ -0,0 +1,34 @@
+using AKSoftware.Localization.MultiLanguages;
+using AKSoftware.Localization.MultiLanguages.Providers;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AKSoftware.Localization.MultiLanguages.WPF
+{
+ public class WpfLanguageContainer: LanguageContainer, INotifyPropertyChanged
+ {
+ public WpfLanguageContainer(IKeysProvider keysProvider) : base(keysProvider) { }
+
+ public WpfLanguageContainer(CultureInfo culture, IKeysProvider keysProvider) : base(culture, keysProvider)
+ { }
+
+ public override void SetLanguage(CultureInfo culture)
+ {
+ base.SetLanguage(culture);
+ OnPropertyChanged("");
+ }
+
+ #region INotifyPropertyChanged
+ public event PropertyChangedEventHandler? PropertyChanged;
+ protected void OnPropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/AKSoftware.Localization.MultiLanguages.sln b/src/AKSoftware.Localization.MultiLanguages.sln
index 38b9ee5..dd9336e 100644
--- a/src/AKSoftware.Localization.MultiLanguages.sln
+++ b/src/AKSoftware.Localization.MultiLanguages.sln
@@ -27,7 +27,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AKSoftware.Localization.MultiLanguages.Benchmarks", "AKSoftware.Localization.MultiLanguages.Benchmarks\AKSoftware.Localization.MultiLanguages.Benchmarks.csproj", "{F5614460-91AC-4F56-A431-C3916066E045}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppSample", "ConsoleAppSample\ConsoleAppSample.csproj", "{FDD40575-C8FA-4C55-B157-C15045E1CC59}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleAppSample", "ConsoleAppSample\ConsoleAppSample.csproj", "{FDD40575-C8FA-4C55-B157-C15045E1CC59}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AKSoftware.Localization.MultiLanguages.WPF", "AKSoftware.Localization.MultiLanguages.WPF\AKSoftware.Localization.MultiLanguages.WPF.csproj", "{45FB19ED-6455-49D9-954C-F51F30D890D5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfSampleApp", "WpfSampleApp\WpfSampleApp.csproj", "{3A39FD7F-5649-4255-9E91-BC7D4C25C291}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -255,6 +259,46 @@ Global
{FDD40575-C8FA-4C55-B157-C15045E1CC59}.Release|x64.Build.0 = Release|Any CPU
{FDD40575-C8FA-4C55-B157-C15045E1CC59}.Release|x86.ActiveCfg = Release|Any CPU
{FDD40575-C8FA-4C55-B157-C15045E1CC59}.Release|x86.Build.0 = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|ARM.Build.0 = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|x64.Build.0 = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Debug|x86.Build.0 = Debug|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|ARM.ActiveCfg = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|ARM.Build.0 = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|ARM64.Build.0 = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|x64.ActiveCfg = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|x64.Build.0 = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|x86.ActiveCfg = Release|Any CPU
+ {45FB19ED-6455-49D9-954C-F51F30D890D5}.Release|x86.Build.0 = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|ARM.Build.0 = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|x64.Build.0 = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Debug|x86.Build.0 = Debug|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|ARM.ActiveCfg = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|ARM.Build.0 = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|ARM64.Build.0 = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|x64.ActiveCfg = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|x64.Build.0 = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|x86.ActiveCfg = Release|Any CPU
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -267,6 +311,7 @@ Global
{8EA5EEEA-B317-4A54-8ACC-6CE0968E13EB} = {250EFD8C-4FB7-419C-8155-B81CFB193975}
{F5614460-91AC-4F56-A431-C3916066E045} = {5270185F-FF5C-49EE-AAE3-11BAF2388341}
{FDD40575-C8FA-4C55-B157-C15045E1CC59} = {250EFD8C-4FB7-419C-8155-B81CFB193975}
+ {3A39FD7F-5649-4255-9E91-BC7D4C25C291} = {250EFD8C-4FB7-419C-8155-B81CFB193975}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C0B8EEB9-C64F-4B59-8C57-872A2D48659E}
diff --git a/src/AKSoftware.Localization.MultiLanguages/AKSoftware.Localization.MultiLanguages.csproj b/src/AKSoftware.Localization.MultiLanguages/AKSoftware.Localization.MultiLanguages.csproj
index ccbcc4a..1d1343f 100644
--- a/src/AKSoftware.Localization.MultiLanguages/AKSoftware.Localization.MultiLanguages.csproj
+++ b/src/AKSoftware.Localization.MultiLanguages/AKSoftware.Localization.MultiLanguages.csproj
@@ -25,7 +25,7 @@
-
+
@@ -37,7 +37,7 @@
True
-
+
diff --git a/src/AKSoftware.Localization.MultiLanguages/LanguageContainer.cs b/src/AKSoftware.Localization.MultiLanguages/LanguageContainer.cs
index d761c5c..d8fc0d9 100644
--- a/src/AKSoftware.Localization.MultiLanguages/LanguageContainer.cs
+++ b/src/AKSoftware.Localization.MultiLanguages/LanguageContainer.cs
@@ -54,7 +54,7 @@ public LanguageContainer(IKeysProvider keysProvider) : this(CultureInfo.CurrentC
///
/// The required culture
/// To indicates if this is the initial function
- private void SetLanguage(CultureInfo culture, bool isDefault)
+ protected virtual void SetLanguage(CultureInfo culture, bool isDefault)
{
CurrentCulture = culture;
Keys = _keysProvider.GetKeys(culture);
@@ -66,7 +66,7 @@ private void SetLanguage(CultureInfo culture, bool isDefault)
/// Set language manually based on a specific culture
///
/// The required culture
- public void SetLanguage(CultureInfo culture)
+ public virtual void SetLanguage(CultureInfo culture)
{
CurrentCulture = culture;
Keys = _keysProvider.GetKeys(culture.Name);
diff --git a/src/UwpAkLocalization/UwpAkLocalization.csproj b/src/UwpAkLocalization/UwpAkLocalization.csproj
index 51a593c..7f6e8e8 100644
--- a/src/UwpAkLocalization/UwpAkLocalization.csproj
+++ b/src/UwpAkLocalization/UwpAkLocalization.csproj
@@ -11,7 +11,7 @@
UwpAkLocalization
en-US
UAP
- 10.0.18362.0
+ 10.0.19041.0
10.0.17134.0
14
512
diff --git a/src/WpfSampleApp/App.xaml b/src/WpfSampleApp/App.xaml
new file mode 100644
index 0000000..d0499a6
--- /dev/null
+++ b/src/WpfSampleApp/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/src/WpfSampleApp/App.xaml.cs b/src/WpfSampleApp/App.xaml.cs
new file mode 100644
index 0000000..b3ad74b
--- /dev/null
+++ b/src/WpfSampleApp/App.xaml.cs
@@ -0,0 +1,21 @@
+using AKSoftware.Localization.MultiLanguages.Providers;
+using AKSoftware.Localization.MultiLanguages.WPF;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace WpfSampleApp
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App: Application
+ {
+ public static readonly WpfLanguageContainer LanguageContainer
+ = new(new("en-us"), new FolderResourceKeysProvider("Resources"));
+ }
+}
diff --git a/src/WpfSampleApp/AssemblyInfo.cs b/src/WpfSampleApp/AssemblyInfo.cs
new file mode 100644
index 0000000..8b5504e
--- /dev/null
+++ b/src/WpfSampleApp/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/src/WpfSampleApp/MainWindow.xaml b/src/WpfSampleApp/MainWindow.xaml
new file mode 100644
index 0000000..ef8ed9d
--- /dev/null
+++ b/src/WpfSampleApp/MainWindow.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WpfSampleApp/MainWindow.xaml.cs b/src/WpfSampleApp/MainWindow.xaml.cs
new file mode 100644
index 0000000..5e76623
--- /dev/null
+++ b/src/WpfSampleApp/MainWindow.xaml.cs
@@ -0,0 +1,101 @@
+using AKSoftware.Localization.MultiLanguages;
+using System.Reflection;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Text.RegularExpressions;
+
+namespace WpfSampleApp
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow: Window
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+
+ // getting language files list from embedded resources
+ var assembly = Assembly.GetExecutingAssembly();
+ var languageFiles =
+ assembly.GetManifestResourceNames()
+ .Where(t => Regex.IsMatch(t, @"\.([A-Za-z]{2}-[A-Za-z]{2}).ya?ml$"))
+ .ToDictionary(
+ t =>
+ {
+ // just for proof-of-concept, there might be a better solution for this
+ var m = Regex.Match(t, @"\.([A-Za-z]{2}-[A-Za-z]{2}).ya?ml$");
+ return m.Groups[1].Value;
+ },
+ t => t
+ );
+ YamlDotNet.Serialization.Deserializer deserializer = new();
+
+ foreach (var languageFile in languageFiles)
+ {
+ using var stream = assembly.GetManifestResourceStream(languageFile.Value);
+ if (stream is null) continue;
+
+ byte[] s = new byte[stream.Length];
+ stream.Read(s);
+ string st = Encoding.UTF8.GetString(s);
+
+ var obj = deserializer.Deserialize>(st);
+ var names = ((Dictionary