Die DescriptionAtribute-Klasse kann im Konstruktor nur eine konstante Zeichenfolge entgegen nehmen. Das ist problematisch, wenn man mehrsprachig arbeiten möchte. Microsoft nutzt intern eine eigene Klasse (SRDescription(Name As String)), die den Text aus der Ressourcen-Datei lädt. Diese wiederum ist lokalisierbar. Leider ist SRDescription nicht öffentlich. Hier eine entsprechende Variante.
Ähnliches gilt für die CatagoryAttribute-Klasse. Ebenfalls wird die selbst entwickelte UrsDisplayNameAttribute-Klasse "ressourcenfähig" gemacht, die das DisplayNameAttribute erweitert.
Die Klasse UrsSRDescriptionAttribute wird wie die DescriptionAttribute-Klasse verwandt. Statt des beschreibenden Textes wird jedoch der Name einer Zeichenfolge in der Ressourcen-Datei übergeben.
Diese Klasse kann nicht direkt verwandt werden. Bei Projekten, die aus mehreren Assemblies bestehen, muss klar geregelt sein, welches Assembly die Ressourcen bereit stellt. Ohne weitere Maßnahmen würde eine Instanz von UrsSRDescriptionAttribute die Zeichenfolgen in den Ressourcen des Projekts UrsLibrary suchen. Das macht i.d.R. wenig Sinn.
Damit auf die richtigen Ressourcen zugegriffen wird, muss UrsSRDescriptionAttribute in dem Projekt abgeleitet werden, dessen Ressourcen verwandt werden sollen. Über die abgeleitete Klasse kann dann sehr einfach auf die Ressourcen des entsprechenden Projekt-Assemblies zugegriffen werden. Dazu ist es lediglich notwendig, Methode GetResourceString zu implementieren. Die einzige Anweisung in der Methode ist:
Return My.Resources.ResourceManager.GetString(Name)
My.Resources.ResourceManager greift auf die My-Ressourcen zu und das sind die des Projekt-Assemblies. Soll auf andere Ressourcen zugegriffen werden, ist diese Methode zu modifizieren.
Das folgende Beispiel implementiert die Klasse UrsLibSRDescriptionAttribute, die, weil in UrsLibray definiert, die Beschreibungstexte aus den Ressourcen der Library lädt.
Friend NotInheritable Class UrsLibSRDescriptionAttribute
Inherits UrsSRDescriptionAttribute
Public Sub New(Name As String)
MyBase.New(Name)
End Sub
Protected Overrides Function GetResourceString(Name As String) As String
Return My.Resources.ResourceManager.GetString(Name)
End Function
End Class
Verwandt wird diese Klasse dann wie folgt:
<UrsLibSRDescriptionAttribute("ProgressBarValueDescr")>
Public Property Value As Integer
Der String mit dem Namen "ProgressBarValueDescr" muss dann in der Ressource definiert werden. Geschieht dies nicht, liefert die Attribut-Klasse einen leeren String.
Die Verwendung des UrsSRCategoryAttribute erfolgt analog. Auch diese Klasse ist abzuleiten und die Methode GetResourceString zu implementieren. Hier das Beispiele für eine abgeleitete Klasse, die die Ressourcen aus dem UrsLibrary-Projekt lädt:
Friend NotInheritable Class UrsLibSRCategoryAttribute
Inherits UrsSRDCategoryAttribute
Public Sub New(Name As String)
MyBase.New(Name)
End Sub
Protected Overrides Function GetResourceString(Name As String) As String
Return My.Resources.ResourceManager.GetString(Name)
End Function
End Class
Verwandt wird diese Klasse dann wie folgt:
<UrsLibSRCategory("CatBehavior")>
Public Property Value As Integer
Der String mit dem Namen "CatBehavior" muss dann in der Ressource definiert werden. Geschieht dies nicht, liefert die Klasse einen leeren String.
Die Verwendung des UrsSRDisplayNameAttribute erfolgt analog. Auch diese Klasse ist abzuleiten und die Methode GetResourceString zu implementieren. Hier das Beispiele für eine abgeleitete Klasse, die die Ressourcen aus dem UrsLibrary-Projekt lädt:
Friend NotInheritable Class UrsLibSRDisplayNameAttribute
Inherits UrsSRDDisplayNameAttribute
Public Sub New(Name As String)
MyBase.New(Name)
End Sub
Protected Overrides Function GetResourceString(Name As String) As String
Return My.Resources.ResourceManager.GetString(Name)
End Function
End Class
Verwandt wird diese Klasse dann wie folgt:
<TypeConverter(GetType(UrsExtendedEnumConverter))>
Public Enum Units
<UrsLibSRDisplayName("UnitInch")>
Inch
End Enum
Der String mit dem Namen "UnitInch" muss dann in der Ressource definiert werden. Geschieht dies nicht, liefert die Klasse einen leeren String. Mögliche Anwendung wäre z.B. die Bezeichnung "Zoll" in der deutschen und "Inch" in der englischen Fassung.