|
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
namespace CBR.Core.Helpers.Localization
{
public class CultureEventArgs : EventArgs
{
public CultureItem Culture { get; set; }
}
/// <summary>
/// Culture event delegate signature
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void CultureEventArrived(object sender, CultureEventArgs e);
/// <summary>
/// Class that manage culture providers (act as a factory) and the UI language. Provide helper functions
/// to get lists and allow to implement a resource provider
/// </summary>
public class CultureManager
{
#region ----------------SINGLETON----------------
/// <summary>
/// Singleton
/// </summary>
public static readonly CultureManager Instance = new CultureManager();
/// <summary>
/// Private constructor for singleton pattern
/// </summary>
private CultureManager()
{
}
#endregion
#region ----------------PROPERTIES----------------
private CultureInfo _uiCulture;
/// <summary>
/// Sets the UICulture for the WPF application and raises the <see cref="UICultureChanged"/>
/// event causing any XAML elements using the <see cref="ResxExtension"/> to automatically
/// update
/// </summary>
public CultureInfo UICulture
{
get
{
if (_uiCulture == null)
{
_uiCulture = Thread.CurrentThread.CurrentUICulture;
}
return _uiCulture;
}
set
{
if (value != UICulture)
{
_uiCulture = value;
Thread.CurrentThread.CurrentUICulture = value;
if (SynchronizeThreadCulture)
{
SetThreadCulture(value);
}
//UICultureExtension.UpdateAllTargets();
MarkupExtensionManager.Instance.UpdateAllTargets();
if (UICultureChanged != null)
UICultureChanged(null, new CultureEventArgs()
{
Culture = CultureManager.Instance.GetAvailableCultures()
.First(p => p.Culture.TwoLetterISOLanguageName == _uiCulture.TwoLetterISOLanguageName)
});
}
}
}
private bool _synchronizeThreadCulture = true;
/// <summary>
/// If set to true then the <see cref="Thread.CurrentCulture"/> property is changed
/// to match the current <see cref="UICulture"/>
/// </summary>
public bool SynchronizeThreadCulture
{
get { return _synchronizeThreadCulture; }
set
{
_synchronizeThreadCulture = value;
if (value)
{
SetThreadCulture(UICulture);
}
}
}
/// <summary>
/// internal resource provider
/// </summary>
internal IResourceProvider _resProvider = null;
/// <summary>
/// Current resource provider
/// </summary>
internal IResourceProvider Provider
{
get { if (_resProvider == null) _resProvider = GetResourceProvider(); return _resProvider; }
set { _resProvider = value; }
}
#endregion
#region ----------------EVENTS----------------
/// <summary>
/// Raised when the <see cref="UICulture"/> is changed
/// </summary>
/// <remarks>
/// Since this event is static if the client object does not detach from the event a reference
/// will be maintained to the client object preventing it from being garbage collected - thus
/// causing a potential memory leak.
/// </remarks>
public event CultureEventArrived UICultureChanged;
/// <summary>
/// Raised if the available culture list change
/// </summary>
public event CultureEventArrived AvailableCulturesChanged;
#endregion
#region ----------------METHODS----------------
public void Refresh()
{
//UICultureExtension.UpdateAllTargets();
MarkupExtensionManager.Instance.UpdateAllTargets();
}
/// <summary>
/// Return a list of CultureItem discovered by the provider
/// </summary>
/// <returns></returns>
public List<CultureItem> GetAvailableCultures()
{
return Provider.GetAvailableCultures();
}
/// <summary>
/// Return a list of module or resx discovered by the provider
/// </summary>
/// <param name="code2Letter"></param>
/// <returns></returns>
public List<string> GetAvailableModules(string code2Letter)
{
return Provider.GetAvailableModules(code2Letter);
}
/// <summary>
/// Return the resource list of LocalizationItem for a given module
/// </summary>
/// <param name="code2Letter"></param>
/// <param name="modul"></param>
/// <returns></returns>
public List<LocalizationItem> GetModuleResource(string code2Letter, string modul)
{
return Provider.GetModuleResource(code2Letter, modul);
}
/// <summary>
/// Ask the provider to save the resource (if possible...)
/// </summary>
public void SaveResources()
{
if (_resProvider != null)
_resProvider.SaveDefaultResources();
}
/// <summary>
/// This remove a resource from memory, more for developper when update or change the module
/// or the default value to re create the resource (files mode)
/// </summary>
/// <param name="resource"></param>
public void DeleteResource(string code2Letter, string modul, object resource)
{
if (_resProvider != null)
_resProvider.DeleteResource( code2Letter, modul, resource);
}
/// <summary>
/// Ask the provider (if possible...) to create a new culture resource, need to be saved later
/// </summary>
/// <param name="info"></param>
/// <param name="iconFile"></param>
public void CreateCulture(CultureInfo info, string iconFile)
{
if (_resProvider != null)
{
CultureItem item = _resProvider.CreateCulture(info, iconFile);
if (AvailableCulturesChanged != null)
{
AvailableCulturesChanged(null, new CultureEventArgs() { Culture = item });
}
}
}
#endregion
#region ----------------INTERNALS----------------
/// <summary>
/// Retreive a provider based on the configuration
/// </summary>
/// <returns></returns>
private IResourceProvider GetResourceProvider()
{
switch (CBR.Core.Properties.Settings.Default.LocalizeProvider)
{
case ProviderMode.RESX:
return new ResxProvider();
case ProviderMode.XML:
return new XmlProvider();
case ProviderMode.BIN:
return new BinProvider();
default: return null;
}
}
/// <summary>
/// Set the thread culture to the given culture
/// </summary>
/// <param name="value">The culture to set</param>
/// <remarks>If the culture is neutral then creates a specific culture</remarks>
private void SetThreadCulture(CultureInfo value)
{
if (value.IsNeutralCulture)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(value.Name);
}
else
{
Thread.CurrentThread.CurrentCulture = value;
}
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
WPF and MVVM fan, I practice C # in all its forms from the beginning of the NET Framework without mentioning C ++ / MFC and other software packages such as databases, ASP, WCF, Web & Windows services, Application, and now Core and UWP.
In my wasted hours, I am guilty of having fathered C.B.R. and its cousins C.B.R. for WinRT and UWP on the Windows store.
But apart from that, I am a great handyman ... the house, a rocket stove to heat the jacuzzi and the last one: a wood oven for pizza, bread, and everything that goes inside
https://guillaumewaser.wordpress.com/
https://fouretcompagnie.wordpress.com/