About Hasmukh patel

My Photo
Harrow, London, United Kingdom
Dot-Net developer with expertise in Web, WPF, Win-form applications. Have worked on Asp.net,mvc , WPF and Win-forms projects in c#.net language having Sql-Server/Oracle as database with service oriented architecture using test driven development. Having complete knowledge of SDLC and have successfully worked and implemented it on projects.

Language Conversion with WPF

Language Conversion with WPF

In WPF, there is no way to load Label, button and other controls’ content based on your UI culture or allow you to override  UI contents based on your selected language. Using custom MarkupExtension can achieve the goal.  
Example of use of MarkupExtension  with Label

<Label Grid.Column="0" Grid.Row="1" Content="{Extensions:LanguageString Value=Teststring}" />
 

Implementation of MarkupExtension

Note : This is a xml file based example, file name “language-” + culture name.Xml  e.g. “language-en-gb.xml”

[MarkupExtensionReturnType(typeof(string))]
public class LanguageStringExtension : MarkupExtension
{
    #region Properties
 
    /// <summary>
    /// Gets or sets the string that is to be translated.
    /// </summary>
    public string Value { getset; }
    /// <summary>
    /// Gets or sets the format string to be used with the translated string.
    /// e.g. "({0})" to place the translated string in brackets.
    /// </summary>
    public string Format { getset; }
 
 
    #endregion
 
 
    #region Overrides of MarkupExtension
 
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (string.IsNullOrEmpty(Format))
        {
            return LanguageDictionary.Translate(Value);
        }
        return LanguageDictionary.Translate(Value, Format);
    }
 
    #endregion
}

public sealed class LanguageDictionary
{
    //for thread safe access
    private readonly ConcurrentDictionary<string,string> _phrases;
 
    static LanguageDictionary()
    {
        FilesDirectory = Directory.GetCurrentDirectory(); 
        Instance = new LanguageDictionary();
        //load current culture file
        Instance.LoadDictionary(CultureInfo.CurrentUICulture.Name);
    }
 
    //private constructor
    LanguageDictionary()
    {
        _phrases = new ConcurrentDictionary<stringstring>();
    }
 
    public static LanguageDictionary Instance { getprivate set; }
 
    public static string FilesDirectory { getset; }
 
    internal static string Translate(string phrase)
    {
        return Instance.TranslatePhrase(phrase, null);
    }
 
    internal static string Translate(string phrase, string formatString, params object[] prms)
    {
        return Instance.TranslatePhrase(phrase, formatString, prms);
    }
 
    internal static void Load(string culture)
    {
        Instance.LoadDictionary(culture);
    }
 
    internal static void Save()
    {
        Instance.SaveDictionary();
    }
 
    private static string _overrideCulture;
 
    internal static string OverrideCulture
    {
        get { return _overrideCulture; }
        set
        {
            Instance.LoadDictionary(value);
        }
    }
 
    private void SaveDictionary()
    {
        var fileName = GetLanguageFileName();
 
        var xmlDocument = new XmlDocument();
 
        foreach (var kpPhrase in _phrases)
        {
            var node = xmlDocument.CreateNode(XmlNodeType.Element, "Translate"string.Empty);
            node.InnerText = kpPhrase.Value;
 
            var nameAttr = xmlDocument.CreateAttribute("From");
            nameAttr.Value = kpPhrase.Key;
            node.Attributes.Append(nameAttr);
                
            xmlDocument.AppendChild(node);
        }
 
        xmlDocument.Save(fileName);
 
    }
 
    private string GetLanguageFileName()
    {
        return Path.Combine(FilesDirectory,
                            string.Format("language-{0}.xml", _overrideCulture));
    }
 
    private void LoadDictionary(string culture)
    {
        _overrideCulture = culture;
        //clear old values
        _phrases.Clear();
        var fileName = GetLanguageFileName();
 
        if (File.Exists(fileName))
        {
            var xmlDocument = new XmlDocument();
            xmlDocument.Load(fileName);
            foreach (XmlNode childNode in xmlDocument.ChildNodes)
            {
                _phrases.TryAdd(childNode.Attributes["From"].Value, childNode.InnerText);
            }
        }
    }
 
    private string TranslatePhrase(string phrase, string formatString, params object[] prms)
    {
        //get value or add for save
        var lanValue = _phrases.GetOrAdd(phrase, phrase);
 
        if (prms == null || prms.Length == 0)
        {
            return lanValue;
        }
        return string.Format(lanValue, prms);
    }
}