Resources from .NET Assemblies

__/~\_/~\__
 »»»»»»»»»»»»»»»          (== | ^ ==)

Accessing string resources from .NET Assemblies

When writing custom controls in .NET we often derive from the original control and override its default functionality to suit our needs. In due course some of the properties of the original may no longer be available, while exposing new properties which are functionally same as a differently named property in the parent.

Since Visual Studio 2005 it is possible to write the customized control to affect the way the designer potrays it. The most visible of these is the ability to define new properties which can be set from the designer when the custom control is used. Further attributes such as - AmbientValueAttribute, BrowsableAttribute, CategoryAttribute, DefaultValueAttribute, DesignOnlyAttribute and DesignTimeVisibleAttribute (all under the System.ComponentModel namespace) enable customizing the behavior of properties of the custom control in the designer.

But the attribute of interest to us is the DescriptionAttribute. This attributes helps in specifying the description associated with a property when it is selected in the property window. This is where a certain amount of resource redundancy comes in. Custom control may override the properties available in the parent control or provide new properties which are functionally similar to a property in the parent. In such cases there is no means to refer to the string resource used by the property in the parent while specifying the description (since the System.Windows.Forms.SRDescriptionAttribute class is internal to the .NET framework assembly and ain't accessible to other assemblies). Invariably duplicate string resources are created.

Here I put forth a simple mechanism to reuse the string resources available in .NET framework assemblies ;). This is a replacement to the DescriptionAttribute, one for each assembly (System, System.Web, System.Drawing and System.Windows.Forms) from which to load the resource. The only catch is instead of specifying the description string as with DescriptionAttribute the name of the string resource is mentioned as with SRDescriptionAttribute. The following code shows the WFDescriptionAttribute which can be used to access string resourced from System.Windows.Forms.

using System;
using System.ComponentModel;
using System.Reflection;
using System.Resources;

namespace Utility
{
public class WFResourceAccessor
{
static WFResourceAccessor()
{
resources = newResourceManager("System.Windows.Forms"
, Assembly.GetAssembly(typeof(System.Windows.Forms.Form)));
}

public static string GetString(string name)
{
return resources.GetString(name);
}

public static string GetString(string name, params object[] args)
{
string fmtString = resources.GetString(name
, System.Globalization.CultureInfo.CurrentCulture);

if ( null == args || 0 >= args.Length )
return fmtString;

for (int index = 0; index < args.Length ;++index)
{
string text = args[index] as string;

if ( null != text && text.Length > 1024 )
args[index] = text.Substring(0, 1021) + "...";
}

returnString.Format(System.Globalization.CultureInfo.CurrentCulture, fmtString, args);
}

private static ResourceManager resources;
}

public class WFDescriptionAttribute : DescriptionAttribute
{
public WFDescriptionAttribute(string description)
: base(description)
{ }

public override string Description
{
get
{
if (false == bReplaced)
{
bReplaced = false;
base.DescriptionValue = WFResourceAccessor.GetString(base.Description);
}

return base.Description;
}
}

private bool bReplaced = false;
}
}

The usage of WFDescriptionAttribute is exactly same as the SRDescriptionAttribute, the usage of which can be found by using .NET Reflector to view the code for standard control such as System.Windows.Forms.ComboBox.