Hi Stefan,
Try deriving classes from System.Resources.ResourceManager and ResourceSet. There are a few protected, virtual methods that you can
override to provide custom functionality. One method of interest would be ResourceManager.InternalGetResourceSet, which you can use
to provide an instance of your custom ResourceSet. Another would be ResourceSet.ReadResources, which you can use to read the
strings from a database.
Here's a working example that you can use. Feel free to extend it or change its behavior completely if you'd like. I added some
caching functionality as well to decrease database hits:
// Here is how you can use the DatabaseResourceManager class, which is defined afterwards:
string message = null;
// english-United States
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
DatabaseResourceManager dbResManager = new DatabaseResourceManager();
message = string.Format("{0} {1}", dbResManager.GetString("hello"), dbResManager.GetString("world"));
Console.WriteLine(message);
// spanish-Spain
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("es-ES");
message = string.Format("{0} {1}", dbResManager.GetString("hello"), dbResManager.GetString("world"));
Console.WriteLine(message);
// french (will choose neutral language)
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fr");
message = string.Format("{0} {1}", dbResManager.GetString("hello"), dbResManager.GetString("world"));
Console.WriteLine(message);
// invariant
System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;
message = string.Format("{0} {1}", dbResManager.GetString("hello"), dbResManager.GetString("world"));
Console.WriteLine(message);
Prints:
hello world
hola mundo
hello world
hello world
Here's my code for the DatabaseResourceManager class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Resources;
using System.Globalization;
using System.Collections;
namespace Synthesoft.Data
{
public class DatabaseResourceManager : ResourceManager
{
public DatabaseResourceManager()
{
}
protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
{
if (culture == null)
culture = CultureInfo.InvariantCulture;
return new DatabaseResourceSet(culture);
}
}
public class DatabaseResourceSet : ResourceSet
{
private readonly CultureInfo culture;
private static readonly Dictionary<string, Hashtable> cachedResources = new Dictionary<string, Hashtable>();
public DatabaseResourceSet(CultureInfo culture)
{
if (culture == null)
throw new ArgumentNullException("culture");
this.culture = culture;
ReadResources();
}
protected override void ReadResources()
{
if (cachedResources.ContainsKey(culture.Name))
// retrieve cached resource set
{
Table = cachedResources[culture.Name];
return;
}
// TODO: grab strings from db based on culture.Name
switch (culture.Name)
{
case "es-ES": // spanish-Spain
// my knowledge of Spanish is very limited
Table["hello"] = "hola";
Table["world"] = "mundo";
break;
case "en-US": // english-United States
default: // invariant language neutral
Table["hello"] = "hello";
Table["world"] = "world";
break;
}
cachedResources[culture.Name] = Table;
}
}
}
--
Dave Sexton
hi,
i like to load the resources (specially the string-table)
from a database table. is this possible ?
e.g. with a custom resource-loader
i know there is such a concept in asp.net (resource provider factory)
but i have nothing
related found for winforms.
thanks,
stefan