using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Reflection; using System.Resources; using System.Threading; using System.Windows.Markup; namespace Developpez.Dotnet.Windows.Localization { /// /// Permet de gérer la localisation d'applications WPF à l'aide de fichiers .resx /// public class LocalizationManager { private static ReadOnlyCollection _availableCultures; /// /// Renvoie la liste des cultures disponibles dans les assemblies satellites de l'application /// public static ReadOnlyCollection AvailableCultures { get { return _availableCultures ?? (_availableCultures = GetAvailableCultures()); } } // Enumère les cultures disponibles dans les assemblies satellites private static ReadOnlyCollection GetAvailableCultures() { List list = new List(); //string startupDir = Environment.CurrentDirectory; string startupDir = AppDomain.CurrentDomain.BaseDirectory; Assembly asm = AssemblyManager.GetEntryAssembly(); CultureInfo neutralCulture = CultureInfo.InvariantCulture; if (asm != null) { NeutralResourcesLanguageAttribute attr = Attribute.GetCustomAttribute(asm, typeof(NeutralResourcesLanguageAttribute)) as NeutralResourcesLanguageAttribute; if (attr != null) neutralCulture = CultureInfo.GetCultureInfo(attr.CultureName); } list.Add(neutralCulture); if (asm != null) { string baseName = asm.GetName().Name; foreach (string dir in Directory.GetDirectories(startupDir)) { // On vérifie que le nom du répertoire correspond à une culture valide DirectoryInfo dirinfo = new DirectoryInfo(dir); CultureInfo tCulture; try { tCulture = CultureInfo.GetCultureInfo(dirinfo.Name); } // Ce n'est pas une culture valide : on ignore l'exception et on passe // au répertoire suivant catch (ArgumentException) { continue; } // On vérifie que le répertoire contient des assemblies satellites if (dirinfo.GetFiles(baseName + ".resources.dll").Length > 0) { list.Add(tCulture); } } } return list.AsReadOnly(); } private static readonly Dictionary _resourceManagersByUri = new Dictionary(); // Tente de récupérer le ResourceManager selon l'URI fournie internal static ResourceManager GetResourceManager(IUriContext uriContext) { ResourceManager resourceManager; Uri baseUri = AssemblyManager.GetRootUri(uriContext); if (_resourceManagersByUri.TryGetValue(baseUri, out resourceManager)) { return resourceManager; } // On récupère l'assembly courant Assembly asm = AssemblyManager.GetAssembly(uriContext); if (asm != null) { // On utilise le jeu de ressources nommé .Properties.Resources string baseName = asm.GetName().Name + ".Properties.Resources"; ResourceManager rm = new ResourceManager(baseName, asm); _resourceManagersByUri.Add(baseUri, rm); return rm; } return null; } /// /// Renvoie ou définit la culture courante de l'interface utilisateur /// public static CultureInfo UICulture { get { return Thread.CurrentThread.CurrentUICulture; } set { Thread.CurrentThread.CurrentUICulture = value; OnUICultureChanged(); } } // Handlers de l'évènement UICultureChanged // On utilise un HashSet pour éviter les doublons private static readonly HashSet _uiCultureChangedHandlers = new HashSet(); /// /// Notifie le changement de culture de l'interface utilisateur /// public static event EventHandler UICultureChanged { add { _uiCultureChangedHandlers.Add(value); } remove { _uiCultureChangedHandlers.Remove(value); } } private static void OnUICultureChanged() { foreach (EventHandler handler in _uiCultureChangedHandlers) { handler(typeof(LocalizationManager), EventArgs.Empty); } } } }