Ich suche nach einer Möglichkeit, in einem PropertyGrid angezeigte Eigenschaftsnamen zu lokalisieren. Der Name der Eigenschaft kann mithilfe des Attributs DisplayNameAttribute "überschrieben" werden. Leider können Attribute keine nicht konstanten Ausdrücke haben. Daher kann ich keine stark typisierten Ressourcen wie Folgendes verwenden:
class Foo
{
[DisplayAttribute(Resources.MyPropertyNameLocalized)] // do not compile
string MyProperty {get; set;}
}
Ich habe mich umgesehen und einen Vorschlag gefunden, von DisplayNameAttribute zu erben, um Ressourcen verwenden zu können. Am Ende würde ich Code haben wie:
class Foo
{
[MyLocalizedDisplayAttribute("MyPropertyNameLocalized")] // not strongly typed
string MyProperty {get; set;}
}
Ich verliere jedoch stark typisierte Ressourcenvorteile, was definitiv keine gute Sache ist. Dann bin ich auf DisplayNameResourceAttribute gestoßen , nach dem ich vielleicht suche. Aber es soll im Microsoft.VisualStudio.Modeling.Design-Namespace sein und ich kann nicht finden, welche Referenz ich für diesen Namespace hinzufügen soll.
Weiß jemand, ob es einen einfacheren Weg gibt, die Lokalisierung von DisplayName auf gute Weise zu erreichen? oder ob es eine Möglichkeit gibt, das zu verwenden, was Microsoft für Visual Studio zu verwenden scheint?
quelle
Antworten:
In .NET 4 gibt es das Display-Attribut von System.ComponentModel.DataAnnotations. Es funktioniert auf der MVC 3
PropertyGrid
.Dadurch wird eine
UserName
in IhrerMyResources
RESX-Datei genannte Ressource nachgeschlagen.quelle
typeof(MyResources)
, müssen Sie möglicherweise den Modifikator für den Zugriff auf Ressourcendateien auf " Öffentlich" setzen .Wir tun dies für eine Reihe von Attributen, um mehrere Sprachen zu unterstützen. Wir haben einen ähnlichen Ansatz wie Microsoft gewählt, bei dem sie ihre Basisattribute überschreiben und einen Ressourcennamen anstelle der eigentlichen Zeichenfolge übergeben. Der Ressourcenname wird dann verwendet, um in den DLL-Ressourcen nach der tatsächlichen Zeichenfolge zu suchen, die zurückgegeben werden soll.
Beispielsweise:
Sie können noch einen Schritt weiter gehen, wenn Sie das Attribut tatsächlich verwenden, und Ihre Ressourcennamen als Konstanten in einer statischen Klasse angeben. Auf diese Weise erhalten Sie Erklärungen wie.
Das Update
ResourceStrings
würde ungefähr so aussehen (beachten Sie, dass sich jede Zeichenfolge auf den Namen einer Ressource bezieht, die die tatsächliche Zeichenfolge angibt):quelle
[MyNamespace].[MyResourceFile].ResourceManager.GetString("MyString");
Hier ist die Lösung, die ich in einer separaten Assembly gefunden habe (in meinem Fall "Common" genannt):
mit dem Code zum Nachschlagen der Ressource:
Typische Verwendung wäre:
Was ziemlich hässlich ist, wenn ich Literalzeichenfolgen als Ressourcenschlüssel verwende. Die Verwendung einer Konstanten würde bedeuten, Resources.Designer.cs zu ändern, was wahrscheinlich keine gute Idee ist.
Fazit: Ich bin damit nicht zufrieden, aber noch weniger glücklich über Microsoft, das für eine so häufige Aufgabe nichts Nützliches bieten kann.
quelle
ResourceManager
Eigenschaften einfach nicht durchlaufen . Stattdessen können Sie die Eigenschaft einfach direkt von dem im Parameter angegebenen Typ abrufen:PropertyInfo property = resourceManagerProvider.GetProperty(resourceKey, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
Mit dem Display- Attribut (aus System.ComponentModel.DataAnnotations) und dem Ausdruck nameof () in C # 6 erhalten Sie eine lokalisierte und stark typisierte Lösung.
quelle
Sie können T4 verwenden, um Konstanten zu generieren. Ich schrieb einen:
quelle
Dies ist eine alte Frage, aber ich denke, dies ist ein sehr häufiges Problem, und hier ist meine Lösung in MVC 3.
Erstens wird eine T4-Vorlage benötigt, um Konstanten zu generieren, um unangenehme Zeichenfolgen zu vermeiden. Wir haben eine Ressourcendatei 'Labels.resx', die alle Beschriftungszeichenfolgen enthält. Daher verwendet die T4-Vorlage die Ressourcendatei direkt.
Anschließend wird eine Erweiterungsmethode erstellt, um den 'Anzeigenamen' zu lokalisieren.
Das Attribut 'DisplayName' wird durch das Attribut 'DisplayLabel' ersetzt, um automatisch aus 'Labels.resx' zu lesen.
Nach all diesen Vorbereitungsarbeiten ist es Zeit, diese Standardvalidierungsattribute zu berühren. Ich verwende das Attribut 'Erforderlich' als Beispiel.
Jetzt können wir diese Attribute in unserem Modell anwenden.
Standardmäßig wird der Eigenschaftsname als Schlüssel zum Nachschlagen von 'Label.resx' verwendet. Wenn Sie ihn jedoch über 'DisplayLabel' festlegen, wird er stattdessen verwendet.
quelle
Sie können DisplayNameAttribute in die Unterklasse i18n einordnen, indem Sie eine der Methoden überschreiben. Wie so. Bearbeiten: Möglicherweise müssen Sie sich mit der Verwendung einer Konstante für den Schlüssel zufrieden geben.
quelle
Ich benutze diese Lösung in meinem Fall
Mit dem Code
quelle
Nun, die Versammlung ist
Microsoft.VisualStudio.Modeling.Sdk.dll
. Dies wird mit dem Visual Studio SDK (mit Visual Studio Integration Package) geliefert.Aber es würde ziemlich genau so verwendet wie Ihr Attribut; Es gibt keine Möglichkeit, stark typisierte Ressourcen in Attributen zu verwenden, nur weil sie nicht konstant sind.
quelle
Ich entschuldige mich für den VB.NET-Code, mein C # ist etwas verrostet ... Aber Sie werden auf die Idee kommen, oder?
Erstellen Sie zunächst eine neue Klasse :
LocalizedPropertyDescriptor
, die erbtPropertyDescriptor
. Überschreiben Sie dieDisplayName
Eigenschaft wie folgt :Some.ResourceManager
ist der ResourceManager der Ressourcendatei, die Ihre Übersetzungen enthält.Implementieren Sie als Nächstes
ICustomTypeDescriptor
in der Klasse die lokalisierten Eigenschaften und überschreiben Sie dieGetProperties
Methode:Sie können jetzt das Attribut 'DisplayName' verwenden, um einen Verweis auf einen Wert in einer Ressourcendatei zu speichern ...
prop_description
ist der Schlüssel in der Ressourcendatei.quelle