Click here to Skip to main content
Click here to Skip to main content

.NET String Resources

By , 19 Apr 2012
 
.NET String Resources - Desktop Demo Application .NET String Resources - Windows Phone Demo Application

Introduction

Internet and globalization have led to the same software being used in different languages, the availability of localized versions. Even if an application is initially only targeting a single language, it is advisable to keep the language dependent elements separate from the actual code, right from the start. Doing so after finishing with the programming is a daunting, time intensive and error prone task.

The .NET framework offers the ResourceManager as a basis for dealing with externalized strings and their translations. This article extends these capabilities of standard .NET string handling by the following functionality:

  • Controlled access to strings
  • Type safe formatting of variable string elements
  • Strings for enumerations (optionally with image)
  • XAML strings
  • User defined string resource files in ASP.NET

An important goal which leads to the presented solution was the uniform usage of the tools in the .NET run time and development environments for:

  • Library/DLL
  • Console application
  • Windows Forms
  • ASP.NET
  • WPF
  • Silverlight
  • Windows Phone 7

The ResStrings library discussed in the following chapters presents a pragmatic and lightweight solution for the handling of string resources.

String Resources

The handling of string resources happens through the StringsResourceManager, which extends its base class ResourceManager with several methods. In addition to GetString the StringsResourceManager offers the method Format, which interprets the content of the resource as a composite format string and applies it to the method String.Format.

The following indicators mark erroneous string resources:

  • UnknownResFormat: Unknown resource - Default=?name?
  • MissingResFormat: Missing resource content - Default=*name*
  • InvalidResFormat: Invalid resource content e.g. for Format - Default=!name!

The usage of these indicators can be turned off with the property UseStringIndicators. The StringsResourceManager is used in a class which is associated with several resource files:

  • MyStrings.cs - declaration of the strings (contains the StringsResourceManager)
    • MyStrings.resx - strings in the default language
    • MyStrings.local.resx - localized strings (optional)

The following example shows the class MyStrings.cs offering some strings:

// ------------------------------------------------------------------------
internal static class MyStrings
{

  // ----------------------------------------------------------------------
  public static string ApplicationInfo
  {
    get { return srm.Format
	( "ApplicationInfo", VersionTool.VersionOf( typeof( MyStrings ) ) ); }
  } // ApplicationInfo

  // ----------------------------------------------------------------------
  public static string CurrentCultureDescription( CultureInfo culture )
  {
    return srm.Format( "CurrentCultureDescription", culture.DisplayName );
  } // CurrentCultureDescription

  // ----------------------------------------------------------------------
  // members
  private static readonly StringsResourceManager srm =
			new StringsResourceManager( typeof( MyStrings ) );

} // class MyStrings

The class is being declared statically so UI-Designers can access the provided strings at development time. With the exception of pure resource libraries, it is advisable to only use this class from within the Assembly, hence it is declared internal. The recycling of strings from other libraries can lead to a dependency nightmare.

Each string is represented as a property or a method and thus ensures that no invalid string references exist at compile time. The method parameters further ensure the correct number and type of arguments for the required formatting parameters.

The next task is the creation of the resource file MyStrings.resx with texts in the default language:

Default language Resources

For each additional language another resource file is created, as the following example for the German language MyStrings.de.resx illustrates:

German language Resources

The usage of the strings in the code is simple and transparent:

Console.WriteLine( MyStrings.ApplicationInfo );
Console.WriteLine( MyStrings.CurrentCultureDescription
		( Thread.CurrentThread.CurrentUICulture ) );

Enumeration Resources

For the localization of enumerations, the library generates an EnumItem via reflection for each of its values. In addition to the enumeration value, each of these EnumItems contains a textual description and has the following special behavior:

  • ToString displays the textual description
  • Equals only compares the enumeration value and ignores the textual description

All values of an enumeration can be accessed in an EnumItemCollection. By implementing IEnumerable it can be used for collection bindings. The StringsResourceManager has special support for enumerations through its method GetEnumItems which creates a new instance of an EnumItemCollection.

Let's assume the following enumeration:

// ------------------------------------------------------------------------
public enum Status
{
  Ok,
  Info,
  Warning,
  Error,
} // enum Status

The integration of this enumeration into the strings class looks as follows:

// ------------------------------------------------------------------------
internal static class MyStrings
{

  // ----------------------------------------------------------------------
  public static EnumItemCollection<Status> StatusItems
  {
    get { return statusItems ?? ( statusItems = srm.GetEnumItems<Status>() ); }
  } // StatusItems

  // ----------------------------------------------------------------------
  // members
  private static EnumItemCollection<Status> statusItems;

  private static readonly StringsResourceManager srm =
			new StringsResourceManager( typeof( MyStrings ) );

} // class MyStrings

The StringsResourceManager loads a string from the resource file for each of the enumeration's values, named according to the pattern EnumType.EnumValue:

Enum item Resources

In case the resource file doesn't contain a text for an enumeration value, its value is used. The following example illustrates the usage of the Status enumeration:

// ------------------------------------------------------------------------
public class StatusDemo
{

  // ----------------------------------------------------------------------
  public StatusDemo( Status status = Status.Ok )
  {
    Status = StatusItems[ status ];
  } // StatusDemo

  // ----------------------------------------------------------------------
  public IEnumerable StatusItems
  {
    get { return MyStrings.StatusItems; }
  } // StatusItems

  // ----------------------------------------------------------------------
  public EnumItem<Status> Status { get; set; }

} // class StatusDemo

For public access to enumerations of a library, it is advisable to declare a utility class which makes the EnumItemCollection available as a property:

// ------------------------------------------------------------------------
public static class StatusHelper
{

  // ----------------------------------------------------------------------
  public static EnumItemCollection<Status> StatusItems
  {
    get { return MyStrings.StatusItems; }
  } // StatusItems

} // class StatusHelper

Enumeration Resources with Images

For WPF, Silverlight and Windows Phone enumerations can be extended with images. The class EnumImageItem additionally contains an image which is loaded from an embedded resource using the following naming convention:

EnumNamespace\{ImagesPath}\EnumType.EnumValue.{ImageExtension}

The values for ImagesPath (Default=Images) and ImageExtension (Default=.png) can be customized in the StringsResourceManager.

Enum item Images

Analogous to EnumItem/EnumItemCollection, all EnumImageItems can be accessed in an EnumImageItemCollection. The method GetEnumImageItems offered by StringsResourceManager generates such a collection.

MVVM Enumerations

To use the strings of enumerations in an MVVM application, it is necessary to integrate the EnumItem respectively the EnumImageItem into the view model:

// ------------------------------------------------------------------------
public class MyViewModel : DependencyObject
{

  // ----------------------------------------------------------------------
  public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(
    "Status",
    typeof( EnumImageItem<Status> ),
    typeof( MyViewModel ),
    null );

  // ----------------------------------------------------------------------
  public IEnumerable StatusItems
  {
    get { return StatusHelper.StatusImageItems; }
  } // StatusItems

  // ----------------------------------------------------------------------
  public EnumImageItem<Status> Status
  {
    get { return (EnumImageItem<Status>)GetValue( StatusProperty ); }
    set { SetValue( StatusProperty, value ); }
  } // Status

} // class MyViewModel

In the XAML view, the textual description of an enumeration value can be displayed using a binding to the property Description. Images from EnumImageItem enumeration values can be used by binding to the property Image:

<ListBox
  ItemsSource="{Binding StatusItems}"
  SelectedItem="{Binding Status, Mode=TwoWay}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel
        Orientation="Horizontal">
        <Image
          Source="{Binding Image.Source}" />
        <TextBlock
          Text="{Binding Description}" />
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Silverlight and Windows Phone

Silverlight and Windows Phone do not offer the possibility to access static objects from within XAML (no x:Static). As a workaround, static resources can be used from a ResourceDictionary. The StringsResourceDictionary is a specialized ResourceDictionary, which automatically loads the string resources and provides them for use in XAML elements. The following files are required for this:

  • MyDictionary.cs - derivation of StringsResourceDictionary
    • MyDictionary.resx - strings in the default language
    • MyDictionary.local.resx - localized strings (optional)

The declaration of the string dictionary looks as follows:

// ------------------------------------------------------------------------
public class MyDictionary : StringsResourceDictionary
{
} // class MyDictionary

Because the strings are directly accessed from the corresponding resource file (.resx), no properties or methods are necessary.

To use the StringsResourceDictionary in XAML, it must be declared as a resource of the main element. Accessing the strings happens via StaticResource:

<Page ...>

  <Page.Resources>
    <app:MyDictionary />
  </Page.Resources>

  <Grid>
    <StackPanel
       Orientation="Horizontal"
      <TextBlock
        Text="{StaticResource MediaDurationLabel}" />
      <TextBlock
        Text="{Binding MediaDuration,
		StringFormat={StaticResource DurationFormatString}}" />
     </StackPanel>
  </Grid>
</Page>

To use several StringsResourceDictionaries together in one XAML, they can be provided with a context:

// ------------------------------------------------------------------------
public class MyAppDictionary : StringsResourceDictionary
{

  // ----------------------------------------------------------------------
  public MyAppDictionary() :
    base( "AppStrings" )
  {
  } // MyAppDictionary

} // class MyAppDictionary

Using a MergedDictionary, several StringsResourceDictionaries can be declared as resources of the XAML element. By prepending the dictionary context, it is possible to reference a resource from a specific resource dictionary:

<Page ...>

  <Page.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <app:MyDictionary />
        <app:MyAppDictionary />
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Page.Resources>

  <Grid>
    <StackPanel
       Orientation="Horizontal"
      <TextBlock
        Text="{StaticResource AppStrings.ApplicationInfoLabel}" />
      <TextBlock
        Text="{StaticResource AppStrings.ApplicationInfo}" />
     </StackPanel>
  </Grid>
</Page>

WPF

When localizing WPF, string resources can be integrated as static values:

<TextBlock
  Text="{x:Static app:MyStrings.MediaDurationLabel}" />
<TextBlock
  Text="{Binding MediaDuration,
	StringFormat={x:Static app:MyStrings.DurationFormatString}}" />

To reduce the management overhead of a strings class, it is possible to use a StringsResourceDictionary analogous to Silverlight/Windows Phone. But this also sacrifices control over invalid string references at design time.

Composite WPF

In certain scenarios, it is desirable to share string resources between WPF and Silverlight/Windows Phone. If no type safety is required for WPF, it is possible to use the StringsResourceDictionary for all systems.

If WPF strings are handled via StringsResourceManager, they can be transferred to the Silverlight/Windows Phone StringsResourceDictionary with the following pattern:

// ------------------------------------------------------------------------
public class MyDictionary : StringsResourceDictionary
{
  // ----------------------------------------------------------------------
  public class MyDictionary :
    base( typeof( MyStrings )
  {
  } // MyDictionary

} // class MyDictionary

ASP.NET

ASP.NET offers the possibility to use string resources through App_GlobalResources and App_LocalResources. But these mechanisms lack support for the following functionality:

  • Dynamically composed strings
  • Strings for enumerations
  • Strings from libraries

Using the StringExpressionBuilder, it is possible to use strings from the StringsResourceManager in a web control via expression binding:

<asp:Label ID="AppTextLabel" runat="server"
	Text="<%$ Strings:MyCompany.MyApp.MyStrings, AppText %>" />
<asp:Label ID="LibTextLabel" runat="server"
	Text="<%$ Strings:MyCompany.MyLib.MyStrings, LibText %>" />

The binding expression supports the following syntax:

<%$ Strings:{TypeName}, {StringName} %>

The type referenced by TypeName has to be declared public and can be one of the following:

  • Static class with strings: StringName represents a public and static method of that class
  • Derivation of StringsResourceManager: StringName represents the name of the resource

In case of a source which derives from StringsResourceManager, the following files are required:

  • MyStrings.cs - derivation of StringsResourceManager
    • MyStrings.resx - strings in the default language
    • MyStrings.local.resx - localized strings (optional)

Because access to the string resources happens directly, no declaration of properties is required and the following syntax is sufficient:

// ------------------------------------------------------------------------
public class MyStrings : StringsResourceManager
{
} // class MyStrings

Based on the StringExpressionEditor, the strings are even available in design mode. The binding is calculated live, which immediately reveals an invalid binding:

Web Design Strings

The declaration of the StringExpressionBuilder is found in the configuration of the web application web.config:

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0">
      <expressionBuilders>
        <add expressionPrefix="Strings"
          type="Itenso.Community.StringResources.ResStrings.StringsExpressionBuilder,
          Itenso.Community.StringResources.ResStrings"/>
      </expressionBuilders>
    </compilation>
  </system.web>
</configuration>

Windows Forms

The concepts presented so far can be used without restrictions in a Windows Forms application. The management of Windows Forms string resources preferably happens through its integrated tools which also support the proper display in design mode.

Library

The ResStrings library is available in the following versions:

Project Content CLR
ResStrings StringsResourceManager
EnumItem
2.0
ResStrings.Web StringsResourceManager
StringExpressionBuilder
EnumItem
2.0 Web
ResStrings.Desktop StringsResourceManager
StringsResourceDictionary
EnumItem
EnumImageItem
4.0 WPF
ResStrings.Silverlight StringsResourceManager
StringsResourceDictionary
EnumItem
EnumImageItem
SL 4
ResStrings.WindowsPhone StringsResourceManager
StringsResourceDictionary
EnumItem
EnumImageItem
SL 4 WP

Each version is accompanied by a sample application. Usage of the ResStrings CLR 2.0 library is demonstrated in a Windows Forms project.

Further information about developing libraries for different platforms can be found in the article Time Period Library for .NET in the chapter Composite Library Development.

The basics concerning localization offered by Microsoft can be found here:

History

  • 20th April, 2012 - v1.2.0.0
    • StringsExpressionParser: Made parsing thread safe
    • Localization: New ASP.NET control for composite localization
    • LocalizationDesigner: Control designer for Localization
    • New example on how to localize the ASP.NET calendar using the new Localization control
  • 13th September, 2011 - v1.1.0.0
    • StringsResourceManager: Added protected default constructor
    • StringsExpressionParser: Added support for StringsResourceManager as source type
  • 11th September, 2011 - v1.0.0.0
    • Initial public release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jani Giannoudis
Software Developer (Senior)
Switzerland Switzerland
Member
Jani is Co-founder of Meerazo.com, a free service which allows to share resources like locations, things, persons and their services in a cooperating group of people.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionget a property by reflectionmembermarcodb8216 Jan '13 - 10:31 
Hy Jani,
couse you are expert in this field i have a Q related to your article. Can you help me?
 
In my vb project i have add a normal Resource file of string.

I have access easily:

My.resources.MyResourceFile.MyString

My String is exposed by a autogenerate property.

Now my question is:

How i can access by reflection at runtime to MyString property value knowing the name of the property (MyString in this example) and the class type MyResourceFile.

I tryed:

 
Dimmystr AsString= My.Resources.MyResourceFile.MyString

 

ClasseFil =
 

GetType(My.Resources.MyResourceFile)

ClasseFil.InvokeMember(ItemsID,
 

 
BindingFlags.GetProperty, Nothing, Nothing, New[Object]() {}).ToString()

But don't work.

Someone can help me?

thks,

Marco
AnswerRe: get a property by reflectionmemberJani Giannoudis18 Jan '13 - 22:55 
You can build a class to access the static properties, like (C#):
// ------------------------------------------------------------------------
public class ResourceAccessor
{
 
  // ----------------------------------------------------------------------
  public string GetStringResource( Type resType, string resName )
  {
    object resourceFile = GetResourceFile( resType );
    PropertyInfo propertyInfo = resType.GetProperty( resName, BindingFlags.NonPublic | BindingFlags.Static );
    return propertyInfo.GetValue( resourceFile, null ) as string;
  } // GetStringResource

  // ----------------------------------------------------------------------
  public T GetResource<T>( Type resType, string resName )
  {
    object resourceFile = GetResourceFile( resType );
    PropertyInfo propertyInfo = resType.GetProperty( resName, BindingFlags.NonPublic | BindingFlags.Static );
    return (T)propertyInfo.GetValue( resourceFile, null );
  } // GetResource

  // ----------------------------------------------------------------------
  private object GetResourceFile( Type resType )
  {
    object resourceFile;
    if ( resourceFiles.TryGetValue( resType, out resourceFile ) == false )
    {
      resourceFile = Activator.CreateInstance( resType, true );
      resourceFiles.Add( resType, resourceFile );
    }
    return resourceFile;
  } // GetResourceFile

  // ----------------------------------------------------------------------
  // members
  private readonly Dictionary<Type,object> resourceFiles = new Dictionary<Type, object>();
 
} // class ResourceAccessor
Please note:
- no error handling provided
- use a cache to speed up the access on multiple resources (member resourceFiles)
- you have two variants: specialized (GetStringResource) and generic (GetResource<T>)
 
And the usage is:
// ------------------------------------------------------------------------
class Program
{
 
  // ----------------------------------------------------------------------
  static void Main()
  {
    ResourceAccessor resourceAccessor = new ResourceAccessor();
    Console.WriteLine( "GetStringResource: " + resourceAccessor.GetStringResource( typeof( MyResourceFile ), "MyString" ) );
    Console.WriteLine( "GetResource<string>: " + resourceAccessor.GetResource<string>( typeof( MyResourceFile ), "MyString" ) );
  } // Main

} // class Program
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralRe: get a property by reflectionmembermarcodb8219 Jan '13 - 8:46 
Thanks very much Jani,
all work well.
There is the possibility also to WRITE the resource property at RUNTIME?
I know that this is not the correct use of the resource file but i would like to know if there is a simple way to do this.
 
Thanks,
Marco
AnswerRe: get a property by reflectionmemberJani Giannoudis19 Jan '13 - 21:29 
Hi Marco,
marcodb82 wrote:
There is the possibility also to WRITE the resource property at RUNTIME?
No. The resource property generated by ResXFileCodeGenerator provides only the get accessor:
internal static string MyString {
  get {
    return ResourceManager.GetString("MyString", resourceCulture);
  }
}
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralMy reviewmemberonurag1929 May '12 - 20:02 
Thumbs Up | :thumbsup:
AnswerRe: My reviewmvpJani Giannoudis29 May '12 - 22:56 
Many thanks. Smile | :)
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralMy vote of 5memberonurag1929 May '12 - 20:02 
Nice
QuestionVery nicememberPatrick Blackman10 May '12 - 15:17 
Love the article, after reading the Time Period one I had to search for all your others. Could this library be made into a MarkupExpression for greater flexiblity so that it could be used in code behind and xaml?
AnswerRe: Very nicemvpJani Giannoudis11 May '12 - 22:16 
Many thanks Patrick
 
For WPF string resources you can use a static class
<TextBlock
    Text="{Binding MediaDuration,
    StringFormat={x:Static app:MyStrings.DurationFormatString}}" />
or the StringsResourceDictionary:
<TextBlock
    Text="{Binding MediaDuration,
    StringFormat={StaticResource DurationFormatString}}" />
 
A custom XAML markup would look like:
<TextBlock
    Text="{Binding MediaDuration,
    StringFormat={local:Loc Key=MyStrings.DurationFormatString}}" />
 
Where do you see the enhanced flexibility of the custom markup?
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

QuestionAn alternative approach for enumerationsmemberGrant Frisken1 May '12 - 12:49 
I might be missing something but it seems like you have to do quite a lot of hand coding of the strings wrapper classes using this approach. I use a different approach (see Localizing .NET Enums[^]) for enums which doesn't require any hand coding (other than adding a TypeConverter attribute to your enums). It also allows you to use the standard ResourceManager with strongly typed wrapper classes auto generated by the standard ResXFileCodeGenerator.
Infralution - we provide .NET solutions:
 
Globalizer - .NET Localization made easy
Infralution Licensing System - simple, secure and affordable licensing
Virtual Tree - superfast, flexible, databound tree/list view

AnswerRe: An alternative approach for enumerationsmvpJani Giannoudis1 May '12 - 20:47 
Hi Grant
 
Many thanks for your feedback.
 
One key point of this design architecture is the separation of code and localization. These are separate aspects, which not always can be joined into the same source code. You may have to localize an enumeration of the .NET framework or one from a third party library.
 
Based on the resulting EnumItem/EnumItemCollection, the user can bind the enumeration as a data source to a list control (WPF/Silverlight/WP7). The EnumItem includes the localization text (property Description) and the enum value, which can be used for further processing. Like the EnumItem you can use the EnumImageItem to represent the enumeration as an image list.
 
And last but not least, from the users point of view, both approaches LocalizedEnumConverter and EnumItem are the same: an additional piece of code to handle the enum localization Wink | ;) .
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralRe: An alternative approach for enumerationsmemberGrant Frisken1 May '12 - 23:01 
You can actually localize enums in .NET Framework and 3rd party libraries using the LocalizedEnumConverter approach as well. You do it by registering the converter for the type eg
 
TypeDescriptor.AddAttributes(typeof(System.Drawing.Drawing2D.DashStyle), new TypeConverterAttribute(typeof(LocalizedEnumConverter)));

Images for enums can be handled by defining a TypeEditor for enumerations which loads images from resources and draws them in the PaintValue method. I've done this for some projects and it works well for Windows Forms controls (like ListBoxes) which will then automatically use the TypeEditor to display the enum value. I'm not sure whether the same mechanism would work for WPF.
Infralution - we provide .NET solutions:
 
Globalizer - .NET Localization made easy
Infralution Licensing System - simple, secure and affordable licensing
Virtual Tree - superfast, flexible, databound tree/list view

GeneralRe: An alternative approach for enumerationsmvpJani Giannoudis1 May '12 - 23:31 
Grant Frisken wrote:
You can actually localize enums in .NET Framework and 3rd party libraries using the LocalizedEnumConverter approach as well.

Thanks for the clarification.
 
Grant Frisken wrote:
I'm not sure whether the same mechanism would work for WPF.
I don't think so. This approach uses the standard XAML binding mechanism.
 
The initial implementation of the EnumItem was within a WPF app, with the goal to separate the enumeration value from his representation. I think one advantage if this approach is the portability (WinForms, ASP.NET, WPF, Silverlight, WP7) and the seamless integration with the remaining (non-enum) localization.
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

QuestionStrongly-typed resource strings. [modified]memberPHS24121 Mar '12 - 4:37 
Jani,
 
You have a knack for turning out useful articles. I've recently dealt with some resource strings of my own recently. A while back, a vendor pointed me to this link:
 
Clickety[^]
 
You might know of it already but I've found it to be a really useful tool-cum-VS addin for generating strongly-typed resource names. Worth looking at and (best of all) it's free. Smile | :)

modified 21 Mar '12 - 12:33.

AnswerRe: Strongly-typed resource strings.mvpJani Giannoudis21 Mar '12 - 21:59 
Hi PHS241
 
PHS241 wrote:
You have a knack for turning out useful articles.
Many thanks Smile | :)
 
PHS241 wrote:
Clickety[^]
No, I didn't know this tool.
 
It looks great, but my personal opinion is:
- string resources should used only internally to reduce the complexity and dependency - with the exception of pure resource binaries
- automatic generated methods for parametrized resources are limiting scenarios like:
// ----------------------------------------------------------------------
  public static string CurrentCultureDescription( CultureInfo culture )
  {
    return srm.Format( "CurrentCultureDescription", culture.DisplayName );
  } // CurrentCultureDescription
- I like to have the full control about the interface/contract to the string resources - not too much magic code Wink | ;)
- all other mentioned drawbacks are handled by the ResSrings library
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralMy vote of 5memberThorsten Bruning14 Sep '11 - 10:01 
Not needing it yet because the lack of multilanguage support for now. but bookmarked it because it seems useful for the time I will come across this. clear to understand.
AnswerRe: My vote of 5memberJani Giannoudis14 Sep '11 - 10:04 
Many thanks Thorsten!
Cheers, Jani Giannoudis

GeneralMy vote of 5memberReiss14 Sep '11 - 0:23 
Another fantastic article (as I expected when I saw your name as author) especially around Enums, well laid out and simple to follow.
AnswerRe: My vote of 5memberJani Giannoudis14 Sep '11 - 8:30 
Many thanks Reiss, I'm glad you like the Enum approach.
Cheers, Jani Giannoudis

GeneralMy vote of 5memberKenBonny13 Sep '11 - 21:01 
Easy to understand if you know a bit about the part you're reading about.
AnswerRe: My vote of 5memberJani Giannoudis14 Sep '11 - 8:28 
Many thanks!
It's true, some basic knowledge is required Smile | :) .
Cheers, Jani Giannoudis

QuestionHow to let Strings.cs contains two or more res filesmembersdspringyang13 Sep '11 - 20:40 
Jani,
Could you please tell me how can you put two res files under Strings.cs?
 
Thanks,
BD
AnswerRe: How to let Strings.cs contains two or more res filesmemberJani Giannoudis13 Sep '11 - 20:57 
Hi sdspringyang
 
Use the following steps to add resource files to Strings.cs:
1) Project > Add New Item (Ctrl-Shift-A)
2) Installed Templates: Visual C# > General > Resource File
3) Name: Strings.res > Add
4) Visual Studio adds the new resource file below Strings.cs
 
Repeat the steps for a localization like Strings.zh.res.
Cheers, Jani Giannoudis

GeneralRe: How to let Strings.cs contains two or more res filesmembersdspringyang13 Sep '11 - 21:04 
Jani,
Got it.
 
Thanks for your help.
QuestionVery nicememberCIDev12 Sep '11 - 6:53 
A useful and well written article.
Just because the code works, it doesn't mean that it is good code.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 20 Apr 2012
Article Copyright 2011 by Jani Giannoudis
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid