1

Here is the code how I am getting the string value from the resource file

System.Resources.ResourceManager rsMgr = new System.Resources.ResourceManager("DemoResourceLocalization.ErrorMessageResource"
System.Reflection.Assembly.GetExecutingAssembly());
string value = rsMgr.GetString("PersonName");
M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118
varkhedi
  • 13
  • 1
  • 8

1 Answers1

0

If you want to change the resources programmatically, you should work either with the .resx files directly or use some custom writable resource database.

You can use the ResXResourceReader and ResXResourceWriter classes to read the strings into a dictionary and at the end write them back into a new .resx file.

public static class DynamicResourceManager
{
    private static readonly Dictionary<string, string> dictionary;

    // are there any changes
    private static bool isDirty = false;

    // The current language of the resources to manage
    private static CultureInfo activeLanguage = CultureInfo.CurrentUICulture;

    public static CultureInfo ActiveLanguage
    {
        get { return activeLanguage; }
        set
        {
            if (value == null)
                throw new ArgumentNullException("value");

            if (!activeLanguage.Equals(value))
            {
                if (isDirty)
                    SaveDictionary();

                activeLanguage = value;
                LoadDictionary();
            }
        }
    }

    private static void LoadDictionary()
    {
        // The ResourceManager is case-insensitive so we are, too
        if (dictionary == null)
             dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        else
            dictionary.Clear();

        string file = GetFileName();
        if (!File.Exists(file))
            return;

        using (IResourceReader reader = new ResXResourceReader(file))
        {
            foreach (DictionaryEntry item in reader)
            {
                string value = item.Value as string;
                if (value != null)
                    dictionary.Add(item.Key.ToString(), value);
            }
        }
    }

    // this should be called explicitly when you exit the application, but
    // is called automatically when ActiveLanguage is changed
    public static void SaveDictionary()
    {
        if (!isDirty)
            return;

        string file = GetFileName();
        string dir = Path.GetDirectoryName(file);

        if (!Directory.Exists(dir))
            Directory.CreateDirectory(dir);

        using (IResourceWriter writer = new ResXResourceWriter(file))
        {
            foreach (KeyValuePair<string, string> item in dictionary)
                writer.AddResource(item.Key, item.Value);
        }

        isDirty = false;            
    }

    private static string GetFileName()
    {
        return Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Languages") + activeLanguage.Name + ".resx");
    }

    public static string GetString(string key)
    {
        if (key == null)
            return String.Empty;

        if (dictionary == null)
            LoadDictionary();

        string result;
        if (!dictionary.TryGetValue(key, out result))
        {
            // entry not found in this language, adding it dynamically
            dictionary.Add("NEW:" + key, key);
            isDirty = true;
        }

        return result;
    }

    public static void SetString(string key)
    {
        if (dictionary == null)
            LoadDictionary();

        dictionary[key] = value;
        isDirty = true;
    }
}

Incompatibilities with the ResourceManager class:

  • Does not handle culture hierarchy (eg. en-US -> en -> Invariant).
  • Ignores non-string resources

Update 2019:

Recently I made my libraries open source, which supports dynamic resource management. Unlike the sample above, it does not need a reference to System.Windows.Forms.dll because it has its own resource reader/writer implementation.

György Kőszeg
  • 17,093
  • 6
  • 37
  • 65
  • Thanks for the solution .its working fine but on the next run of the application the updated value is displayed not at that run .Any idea how i can resolve this issue – varkhedi Sep 28 '15 at 12:31
  • Maybe the dictionary was not initialized because you did not change the `ActiveLanguage`. I have edited the answer. See the `dictionary` field, `GetString` and `LoadDictionary`. – György Kőszeg Sep 28 '15 at 12:43
  • And do not forget to call the public `SaveDictionary` before you exit the application. – György Kőszeg Sep 28 '15 at 12:53
  • Thanks a lot !!ONCE IT WORKS I WILL UPDATE YOU:):) – varkhedi Sep 28 '15 at 13:03