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);
}
}
}
}