|
Hello,
I´m trying to localize it the way proposed but can't get it to work:
I have a separate dll "Enums.dll" which holds all my enums. I`ve referenced Infralution.Localization.dll, added some .resx files considering the naming convention, created the class "LocalizedEnumConverter" and added the appropriate attribute to my enums.
Calling Enum.GetValues(typeof(MyEnum)) ends up that no localization of the enum members is done, I always get the enum values itself?
Can anybody show me the way out of this?
Thanks,
rzddr
|
|
|
|
|
Is your application a Windows Forms app or an ASP.NET app? If it is an ASP.NET app then make sure you have read the section in the article about ASP.NET apps.
Are you assigning Enum.GetValues(typeof(MyEnum)) to a control datasource - or just looking at the values in the debugger. The values returned by Enum.GetValues aren't changed - they are still enum values. What does changes is the way control display these values. Standard Windows forms controls use the associated type converter to convert the enum values returned by Enum.GetValues into text.
If you have assigned Enum.GetValues to a control data source (eg a ListBox) and you don't have the correct resources defined then you should still see the resource names displayed in the control (instead of the actual enum values) eg "MyEnum_Red", "MyEnum_Blue". If instead you are just seeing the simple values eg "Red", "Blue" then it means the LocalizedEnumConverter is not being used.
|
|
|
|
|
Hello Grant,
thank you very much for your quick response!
I`ve checked my context by assigning the values returned by Enum.GetValues to the DataSource property of a ListBox and it worked.
However, my application is a class library (Enums.dll) and I want this assembly to return the localized enum values independently.
So how can I emulate the behaviour of the DataSource property?
Regards,
rz
|
|
|
|
|
I don't quite understand what you want to do. With the solution you have implemented currently if clients of your application use the enum values as a data source for controls then the localized text will be displayed. In what other circumstances would you want to get the localized text?
If you do want to provide access to the localized text for some other reason then you can could provide a method that calls LocalizedEnumConverter.GetValues(typeof(SampleEnum)) and returns the mapping from enum value to localized text representation.
|
|
|
|
|
Ok, got that.
My current solution is a class "Localizer" in my Enums.dll which wraps the method LocalizedEnumConverter.GetValues(Type t).
This is actually working.
Basically I would like to have a solution, where the client application does not have to take care of localization issues at all!
That means, there would be no need for her to instantiate an object of type "Localizer" and call the appropriate method to get the localized values. Localization should be working automatically and just by using the enum as it is (not only as data source of control), the values should be translated to the current culture.
Thanks again for helping,
rz
|
|
|
|
|
I have the same issue in a dll...
I have built a separate project with a referenced sub project, this works fine.
My main project is a PIA for Excel (i.e. a .Net Library callable by Excel, which I can only assume has its culture info and ways of loading the assembly)
I have a VB assembly, and reference a built version of your downloaded code (I have had to strongly sign it)
if I create a public enum with the System.ComponentModel.TypeConverter(GetType(LocalizedEnumConverter)) modifier, then call
myE = MyEnum.ItemA
Dim converter As System.ComponentModel.TypeConverter = TypeDescriptor.GetConverter(myE)
? converter.ToString()
"System.ComponentModel.EnumConverter"
whereas in my other project (also a strongly signed assembly, but referenced directly from a newly created stub windows form project), I get the message
? converter.ToString
"ClassLibrary1.LocalizedEnumConverter"
so it look like the LocalizedEnumConverter is not being bound to the enum - any ideas?
Great code, I wish I could use it!
Beats my hack ConvertCamelToSpaced(MyEnumVar.ToString()) hands down.
|
|
|
|
|
Looks like it is probably a peculiarity of the PIA for Excel, possibly related to the way the assembly is loaded. I would post a question to the microsoft.public.excel.programming and microsoft.public.dotnet.general groups.
|
|
|
|
|
I got no reply, but did find an article on unresolved assembly references, to solve the problem:
this will work for an assembly that is loaded but cannot be resolved:
Add a handler for the Assembly Resolution:
Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.AssemblyResolve, AddressOf AssemblyResolve_EventHandler
then to handle the resolution:
Private Function AssemblyResolve_EventHandler(ByVal sender As Object, _
ByVal e As System.ResolveEventArgs) As System.Reflection.Assembly
Dim asm() As System.Reflection.Assembly = System.AppDomain.CurrentDomain.GetAssemblies()
For i As Integer = 0 To asm.Length
If asm(i).FullName = e.Name Then
Return asm(i)
End If
Next
Return Nothing
End Function
|
|
|
|
|
Hi,
I'm facing similar problem.
One of my application is in an assembly, e.g.: ABC.exe
However, the rest of the domain models, enums are in another assembly, e.g. XXX.Domains.dll,
I couldn't get the localization to work, unless I hardcode
<br />
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)<br />
{<br />
if (value != null && destinationType == typeof(string))<br />
{<br />
object result = (_isFlagEnum) ?<br />
GetFlagValueText(culture, value) : GetValueText(culture, value);<br />
return result;<br />
....<br />
}<br />
.........<br />
On top of that, my resource file name couldn't be simply Resources.fr.resx.
If I need to use zh-CN, my resource file name had to be Resource.zh-CN.resx, if I used Resources.zh.resx, it will failed.
how do I resolve the localizing without having to hardcode?
Thanks
|
|
|
|
|
This article is excellent. Yet, there is a bug for the ToolStripComboBox.
If you try to bind the enum to a ToolStripComboBox using toolStripComboBox1.ComboBox.DataSource = Enum.GetValues(typeof(SampleEnum)), you will get nothing displayed.
I found a way to circumvent the problem, but if somebody finds a better and less manual way (as the risk are big that developpers forgot to add the extra code), that would be welcome!
Here's the hack, similar to what's done for ASP.NET but even more manual:
<br />
tooltripComboBox1.ComboBox.BindingContext = this.BindingContext;<br />
toolStripComboBox1.ComboBox.DisplayMember = "Value";<br />
toolStripComboBox1.ComboBox.ValueMember = "Key";<br />
toolStripComboBox1.ComboBox.DataSource = LocalizedEnumConverter.GetValues(typeof(SampleEnum));
Regards,
Chris
www.aulofee.com - infrastructure and security supervision & event correlation
|
|
|
|
|
thank you very much!
this is exactly what i need
Ivan (from Hungary)
|
|
|
|
|
The predecessor to this article, humanizing the enumerations was a good contribution I found to be very helpful. This article is fantastic.
I am currently working with VS 2008 BETA2 and do not have access to the web application project model.
In case someone out there is in the same boat, this small change allows me to use this great contribution in an Visual Web Developer project. This might save someone 30 minutes of research and trial and error.
I added this alternative to the LocalizedEnumConverter.cs file.
public LocalizedEnumConverter(Type type)
: base(type, new ResourceManager("resources." + type.Name, Assembly.Load(new AssemblyName("app_GlobalResources"))))
{
}
|
|
|
|
|
I'm working with VS 2005 and use App_GlobalResources too. But It doesn't work!
And I can't understand why:
new ResourceManager("resources." + type.Name, Assembly.Load(new AssemblyName("app_GlobalResources"))))
Help me please!
Something should remember but some thing should forget. Your life will brighter
modified on Thursday, January 24, 2008 4:13:05 AM
|
|
|
|
|
I also have the same problem.
|
|
|
|
|
Thank you very much providing further help.
I stuck to this point and I read scrap and it solve my problem
|
|
|
|
|
Great job, indeed. Thank you. I included below a working VB code for the resource enum converter hopfully with sufficient attributions to the source. I made a few minor changes to meet design rules per FX Cop 1.36 beta 2.
''' <summary>
''' Defines a type converter for enum values that converts enum values to
''' and from string representations using resources
''' </summary>
''' <remarks>
''' This class makes localization of display values for enums in a project easy. Simply
''' derive a class from this class and pass the ResourceManagerin the constructor.
'''
''' <code lang="C#" escaped="true" >
''' class LocalizedEnumConverter : ResourceEnumConverter
''' {
''' public LocalizedEnumConverter(Type type)
''' : base(type, Properties.Resources.ResourceManager)
''' {
''' }
''' }
''' </code>
'''
''' <code lang="Visual Basic" escaped="true" >
''' Public Class LocalizedEnumConverter
''' Inherits ResourceEnumConverter
''' Public Sub New(ByVal sType as Type)
''' MyBase.New(sType, My.Resources.ResourceManager)
''' End Sub
''' End Class
'''
''' ' Tag the enum with a TypeConverter (using square in place of angle brackets)
''' [System.ComponentModel.TypeConverter(GetType(LocalizedEnumConverter))] _
''' Public Enum MyEnum
''' [System.ComponentModel.Description("None")] None
''' [System.ComponentModel.Description("Description A")] ItemA
''' [System.ComponentModel.Description("Description B")] ItemB
''' End Enum
'''
''' ' Initialize the control to display localized values
''' Me._comboBox.FormattingEnabled = True
'''
''' ' Display localized values
''' ' Because the license enum has a type converter attribute,
''' ' this will automatically display the localized text.
''' Me._comboBox.DataSource = System.Enum.GetValues(GetType(MyEnum))
'''
''' ' get value from localized text
''' Dim converter As TypeConverter = TypeDescriptor.GetConverter(GetType(MyEnum))
''' Dim value As Object = converter.ConvertFromString(MyTextValue)
'''
''' </code>
'''
'''
''' Then define the enum values in the resource editor. The names of
''' the resources are simply the enum value prefixed by the enum type name with an
''' underscore separator eg MyEnum_MyValue. You can then use the TypeConverter attribute
''' to make the LocalizedEnumConverter the default TypeConverter for the enums in your
''' project.
''' </remarks>
''' <history date="10/18/2007" by="David Hary" revision="1.0.2847.x">
''' Copyright 2007 Infralution www.infralution.com
''' Converted to VB.
''' http://www.codeproject.com/csharp/LocalizingEnums.asp
''' </history>
Public Class ResourceEnumConverter
Inherits System.ComponentModel.EnumConverter
Private Class LookupTable
Inherits System.Collections.Generic.Dictionary(Of String, Object)
End Class
#Region " CONSTRUCTORS and DESTRUCTORS "
''' <summary>
''' Create a new instance of the converter using translations from the given resource manager
''' </summary>
''' <param name="type"></param>
''' <param name="resourceManager"></param>
Public Sub New(ByVal type As Type, ByVal resourceManager As System.Resources.ResourceManager)
MyBase.New(type)
_resourceManager = resourceManager
Dim flagAttributes As Object() = type.GetCustomAttributes(GetType(FlagsAttribute), True)
_isFlagEnum = flagAttributes.Length > 0
If _isFlagEnum Then
_flagValues = System.Enum.GetValues(type)
End If
End Sub
#End Region
Private _resourceManager As System.Resources.ResourceManager
Private _isFlagEnum As Boolean
Private _flagValues As Array
Private _lookupTables As System.Collections.Generic.Dictionary(Of Globalization.CultureInfo, LookupTable) = New System.Collections.Generic.Dictionary(Of Globalization.CultureInfo, LookupTable)()
''' <summary>
''' Get the lookup table for the given culture (creating if necessary)
''' </summary>
''' <param name="culture"></param>
''' <returns></returns>
Private Function GetLookupTable(ByVal culture As Globalization.CultureInfo) As LookupTable
Dim result As LookupTable = Nothing
If culture Is Nothing Then
culture = Globalization.CultureInfo.CurrentCulture
End If
If (Not _lookupTables.TryGetValue(culture, result)) Then
result = New LookupTable()
For Each value As Object In GetStandardValues()
Dim text As String = String.Empty
text = GetValueText(culture, value)
If text IsNot Nothing Then
result.Add(text, value)
End If
Next value
_lookupTables.Add(culture, result)
End If
Return result
End Function
''' <summary>
''' Return the text to display for a simple value in the given culture
''' </summary>
''' <param name="culture">The culture to get the text for</param>
''' <param name="value">The enum value to get the text for</param>
''' <returns>The localized text</returns>
''' <history date="10/19/2007" by="David Hary" revision="1.0.2848.x">
''' Add format provider to String.Format.
''' </history>
Private Function GetValueText(ByVal culture As Globalization.CultureInfo, ByVal value As Object) As String
Dim type As Type = value.GetType()
Dim resourceName As String = String.Format(Globalization.CultureInfo.CurrentCulture, _
"{0}_{1}", type.Name, value.ToString())
Dim result As String = _resourceManager.GetString(resourceName, culture)
If result Is Nothing Then
result = resourceName
End If
Return result
End Function
''' <summary>
''' Return true if the given value is can be represented using a single bit
''' </summary>
''' <param name="value"></param>
''' <returns></returns>
''' <history date="10/19/2007" by="David Hary" revision="1.0.2848.x">
''' Mark as shared.
''' </history>
Private Shared Function IsSingleBitValue(ByVal value As ULong) As Boolean
Select Case value
Case 0
Return False
Case 1
Return True
Case Else
Return (value And (value - 1UL)) = 0
End Select
End Function
''' <summary>
''' Return the text to display for a flag value in the given culture
''' </summary>
''' <param name="culture">The culture to get the text for</param>
''' <param name="value">The flag enum value to get the text for</param>
''' <returns>The localized text</returns>
''' <history date="10/19/2007" by="David Hary" revision="1.0.2848.x">
''' Add format provider to Convert.ToUInt32.
''' Add format provider to String.Format.
''' </history>
Private Function GetFlagValueText(ByVal culture As Globalization.CultureInfo, ByVal value As Object) As String
' if there is a standard value then use it
'
If System.Enum.IsDefined(value.GetType(), value) Then
Return GetValueText(culture, value)
End If
' otherwise find the combination of flag bit values
' that makes up the value
'
Dim lValue As ULong = Convert.ToUInt32(value, Globalization.CultureInfo.CurrentCulture)
Dim result As String = Nothing
For Each flagValue As Object In _flagValues
Dim lFlagValue As ULong = Convert.ToUInt32(flagValue, Globalization.CultureInfo.CurrentCulture)
If ResourceEnumConverter.IsSingleBitValue(lFlagValue) Then
If (lFlagValue And lValue) = lFlagValue Then
Dim valueText As String = GetValueText(culture, flagValue)
If result Is Nothing Then
result = valueText
Else
result = String.Format(Globalization.CultureInfo.CurrentCulture, _
"{0}, {1}", result, valueText)
End If
End If
End If
Next flagValue
Return result
End Function
''' <summary>
''' Return the Enum value for a simple (non-flagged enum)
''' </summary>
''' <param name="culture">The culture to convert using</param>
''' <param name="text">The text to convert</param>
''' <returns>The enum value</returns>
Private Function GetValue(ByVal culture As Globalization.CultureInfo, ByVal text As String) As Object
Dim lookupTable As LookupTable = GetLookupTable(culture)
Dim result As Object = Nothing
lookupTable.TryGetValue(text, result)
Return result
End Function
''' <summary>
''' Return the Enum value for a flagged enum
''' </summary>
''' <param name="culture">The culture to convert using</param>
''' <param name="text">The text to convert</param>
''' <returns>The enum value</returns>
''' <history date="10/19/2007" by="David Hary" revision="1.0.2848.x">
''' Add format provider to Convert.ToUInt32.
''' </history>
Private Function GetFlagValue(ByVal culture As Globalization.CultureInfo, ByVal text As String) As Object
Dim lookupTable As LookupTable = GetLookupTable(culture)
Dim textValues As String() = text.Split(","c)
Dim result As ULong = 0
For Each textValue As String In textValues
Dim value As Object = Nothing
Dim trimmedTextValue As String = textValue.Trim()
If (Not lookupTable.TryGetValue(trimmedTextValue, value)) Then
Return Nothing
End If
result = result Or Convert.ToUInt32(value, Globalization.CultureInfo.CurrentCulture)
Next textValue
Return System.Enum.ToObject(EnumType, result)
End Function
''' <summary>
''' Convert string values to enum values
''' </summary>
''' <param name="context"></param>
''' <param name="culture"></param>
''' <param name="value"></param>
''' <returns></returns>
Public Overloads Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
If TypeOf value Is String Then
Dim result As Object
If (_isFlagEnum) Then
result = GetFlagValue(culture, CStr(value))
Else
result = GetValue(culture, CStr(value))
End If
If result Is Nothing Then
result = MyBase.ConvertFrom(context, culture, value)
End If
Return result
Else
Return MyBase.ConvertFrom(context, culture, value)
End If
End Function
''' <summary>
''' Convert the enum value to a string
''' </summary>
''' <param name="context"></param>
''' <param name="culture"></param>
''' <param name="value"></param>
''' <param name="destinationType"></param>
''' <returns></returns>
Public Overloads Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
If Not value Is Nothing AndAlso destinationType Is GetType(String) Then
Dim result As Object
If (_isFlagEnum) Then
result = GetFlagValueText(culture, value)
Else
result = GetValueText(culture, value)
End If
Return result
Else
Return MyBase.ConvertTo(context, culture, value, destinationType)
End If
End Function
''' <summary>
''' Convert the given enum value to string using the registered type converter
''' </summary>
''' <param name="value">The enum value to convert to string</param>
''' <returns>The localized string value for the enum</returns>
Public Overloads Shared Function ConvertToString(ByVal value As System.Enum) As String
Dim converter As System.ComponentModel.TypeConverter = System.ComponentModel.TypeDescriptor.GetConverter(value.GetType())
Return converter.ConvertToString(value)
End Function
''' <summary>
''' Return a list of the enum values and their associated display text for the given enum type
''' </summary>
''' <param name="enumType">The enum type to get the values for</param>
''' <param name="culture">The culture to get the text for</param>
''' <returns>
''' A list of KeyValuePairs where the key is the enum value and the value is the text to display
''' </returns>
''' <remarks>
''' This method can be used to provide localized binding to enums in ASP.NET applications. Unlike
''' windows forms the standard ASP.NET controls do not use TypeConverters to convert from enum values
''' to the displayed text. You can bind an ASP.NET control to the list returned by this method by setting
''' the DataValueField to "Key" and theDataTextField to "Value".
''' </remarks>
''' <history date="10/19/2007" by="David Hary" revision="1.0.2848.x">
''' Make private complying with Microsoft.Design Rule CA1002:DoNotExposeGenericLists
''' </history>
Private Shared Function getValuesList(ByVal enumType As Type, ByVal culture As Globalization.CultureInfo) _
As System.Collections.Generic.List(Of System.Collections.Generic.KeyValuePair(Of [Enum], String))
Dim result As System.Collections.Generic.List(Of System.Collections.Generic.KeyValuePair(Of [Enum], String)) = New System.Collections.Generic.List(Of System.Collections.Generic.KeyValuePair(Of [Enum], String))()
Dim converter As System.ComponentModel.TypeConverter = System.ComponentModel.TypeDescriptor.GetConverter(enumType)
For Each value As System.Enum In System.Enum.GetValues(enumType)
Dim pair As System.Collections.Generic.KeyValuePair(Of [Enum], String) = New System.Collections.Generic.KeyValuePair(Of [Enum], String)(value, converter.ConvertToString(Nothing, culture, value))
result.Add(pair)
Next value
Return result
End Function
''' <summary>
''' Return a read only collection of the enum values and their associated display text for the given enum type
''' </summary>
''' <param name="enumType">The enum type to get the values for</param>
''' <param name="culture">The culture to get the text for</param>
''' <returns>
''' A list of KeyValuePairs where the key is the enum value and the value is the text to display
''' </returns>
''' <remarks>
''' This method can be used to provide localized binding to enums in ASP.NET applications. Unlike
''' windows forms the standard ASP.NET controls do not use TypeConverters to convert from enum values
''' to the displayed text. You can bind an ASP.NET control to the list returned by this method by setting
''' the DataValueField to "Key" and theDataTextField to "Value".
''' </remarks>
''' <history date="10/19/2007" by="David Hary" revision="1.0.2848.x">
''' Expose in place of the List complying with Microsoft.Design Rule CA1002:DoNotExposeGenericLists
''' </history>
Public Shared Function GetValues(ByVal enumType As Type, ByVal culture As Globalization.CultureInfo) _
As System.Collections.ObjectModel.ReadOnlyCollection(Of System.Collections.Generic.KeyValuePair(Of [Enum], String))
Return New ObjectModel.ReadOnlyCollection(Of System.Collections.Generic.KeyValuePair(Of [Enum], String))(getValuesList(enumType, culture))
End Function
''' <summary>
''' Return a list of the enum values and their associated display text for the given enum type in the current UI Culture
''' </summary>
''' <param name="enumType">The enum type to get the values for</param>
''' <returns>
''' A list of KeyValuePairs where the key is the enum value and the value is the text to display
''' </returns>
''' <remarks>
''' This method can be used to provide localized binding to enums in ASP.NET applications. Unlike
''' windows forms the standard ASP.NET controls do not use TypeConverters to convert from enum values
''' to the displayed text. You can bind an ASP.NET control to the list returned by this method by setting
''' the DataValueField to "Key" and theDataTextField to "Value".
''' </remarks>
''' <history date="10/19/2007" by="David Hary" revision="1.0.2848.x">
''' Expose in place of the List complying with Microsoft.Design Rule CA1002:DoNotExposeGenericLists
''' </history>
Public Shared Function GetValues(ByVal enumType As Type) _
As System.Collections.ObjectModel.ReadOnlyCollection(Of System.Collections.Generic.KeyValuePair(Of [Enum], String))
Return GetValues(enumType, Globalization.CultureInfo.CurrentUICulture)
End Function
End Class
|
|
|
|
|
Thanks for that work - I'm sure it will be useful for our VB.NET friends
|
|
|
|
|
Damn! I wish I'd read your comment before I spent an hour converting it to VB.NET myself
|
|
|
|
|
Very well done. 5 from me
|
|
|
|
|
class UiNamedAttribute : System.Attribute {
public string Name { get { return FName; } }
public string NamePlural { get { return FNamePlural; } }
public UiNamedAttribute(string name) {
this.FName = name;
this.FNamePlural = name+"s"; }
public UiNamedAttribute(string name, string namePlural) {
this.FName = name;
this.FNamePlural = namePlural; }
private string FName, FNamePlural;
}
enum SampleNamedEnum {
[UiNamed("Entry Point")]
EntryPoint,
[UiNamed("Axis", "Axes")]
Axis,
[UiNamed("Species", "Species")]
Species,
Apple,
}
Now, it needs the method to extract the both forms of the name from the enumeration value.
Also, this '+"s"' is not localizable, so one may want to globalize this version of UiNamedAttribute.
Do I have to explain how to do this?
I would prefer to leave it for a home assignment for a reader...
Thank you
Sergey A Kryukov
http://www.SAKryukov.org
|
|
|
|
|
The method you have provided does not provide for localization of the enum values and requires more code for each enumeration value. There are quite a few articles on code project (including the one referenced in my article) that use this type of technique for customizing enum value. The point of this article is to provide an easy mechanism for localizing enumeration values.
|
|
|
|
|
> The point of this article is to provide an easy mechanism for localizing enumeration values.
Yes, I know. But my point is that even the localization is easier with my approach. I thought it was clear enough, so I did not bother to show this technique. My fault, then. Well, do I really have to show how to do this kind of localization?
The point is: my approach follows what I call just-in-right-place coding conception.
Ok, if you disagree, I can publish some code to show the difference. After all, it is also a matter of taste, at least a part of this problem. Anyway, I hope this whole discussion can be useful for the readers.
Sergey A Kryukov
http://www.SAKryukov.org
|
|
|
|
|
I must apologize. I was not right.
Yes, to globalize enum naming, I would need something very close to your approach, anyway. It is nearly optimal.
Still, I can see a couple of problems that you could fix.
First, one may apply TypeConverter attribute but supply resource string only for some of the enum values or even none of them (does not matter for what locale – one of them or more). This is quite a normal situation.
For example, let’s assume that “SampleEnum_Small” resource Id is missing. Your implementation “falls back” the the value SampleEnum_Small.
What it should do is fallback to the value “Small”, t.i. such a default value must be extracted from enum value definition via reflection.
Second thing, I know from my practice that one pretty often needs at least two different forms of the string denoting a enum value (usually singular and plural), as I demonstrated using two forms of the term in my attribute constructor. With localization, however, it is probably not possible to find a comprehensive solution. In my own native language, for example, the word “small” would take at least 12 forms, some of them spelled identically. You really need some of them when you generate a phrase automatically out of template. In English, for example, you would need just two cases to spell out without an ugly grammar violation: e.i. “0 files found”, “12 files found”, “1 file found”, but not “1 files found”, as many programs awkwardly say. When “file” not a constant string but a enum parameter (apples, pears, etc.) a template like “{0} {1} found” would do the trick, where {1} is replaced with the string value provided by your TypeConverter attribute.
I would suggest having just two simplest forms as a minimal common denominator, but with different cultures you never know…
Again, please accept apologizies for my previous misleading comment. I will also fix my comment to the Joe Sonderegger's works (http://www.codeproject.com/useritems/Lasy_Enum_Readability.asp).
Thank you.
Sergey A Kryukov
http://www.SAKryukov.org
|
|
|
|
|
SAKryukov wrote: For example, let’s assume that “SampleEnum_Small” resource Id is missing. Your implementation “falls back” the the value SampleEnum_Small.
What it should do is fallback to the value “Small”, t.i. such a default value must be extracted from enum value definition via reflection.
The reason it falls back to SampleEnum_Small rather than Small is because when you do localization it is important to be able identify early on in the development process items which have not been localized. Since "SampleEnum" sticks out (is very obviously wrong) you quickly identify the fact that you haven't included the localized resources for the enum and fix it. If you don't do this upfront - then when you get to actually localizing to a different language you discover you have a lot of code changes to do.
|
|
|
|
|
Grant, I got your point -- you're right about early problem detection.
But! something like "SampleEnum" DOES NOT stick out, really (especially in presence of many localized versions of the term).
What you really want is to use Debug.Assert for early detection of the lack of resource -- on par with other assertion which serve the same purpose.
Could you do that?
If you can, you also may want to offer a (pretty usual) choice: whether to allow falling back to source-coded enum value (via reflection) or raise the exception via that assertion. How about that?
Thank you.
Sergey A Kryukov
|
|
|
|
|