开源软件名称(OpenSource Name):codingseb/Localization开源软件地址(OpenSource Url):https://github.com/codingseb/Localization开源编程语言(OpenSource Language):C# 100.0%开源软件介绍(OpenSource Introduction):LocalizationA suit of libs to localize C# and WPF projects easily based on file format you choose. Replace the archived TranslateMe lib
The differents parts of the projectThe library is composed of 4 parts :
InstallationWith NugetFor Simple C# projects
or
or
and implement your own FileLoader. For WPF projects
and
Use it in C# :To localize a text using CodingSeb.Localization
/// ...
// To translate a text in the current language
// Loc.Tr("TextId");
Loc.Tr("SayHello");
// To show a default text if the text is not localized in the current language
// Loc.Tr("TextId", "DefaultText")
Loc.Tr("SayHello", "Not localized");
// To Translate a text in fixed language
// Loc.Tr("TextId","DefaultText" "LanguageId");
Loc.Tr("SayHello", null, "fr");
To Change the current language Loc.Instance.CurrentLanguage = "en";
Loc.Instance.CurrentLanguage = "fr";
Loc.Instance.CurrentLanguage = "es";
// ...
// To get availables languages
Collection<string> languages = Loc.Instance.AvailableLanguages; Use it In XAML (WPF) :(no xmlns needed Tr Markup is available as soon as CodingSeb.Localization.WPF is in project's references) Simple localization with the Markup <TextBlock Text="{Tr 'SayHello'}"/>
<TextBlock Text="{Tr 'SayHello', DefaultText='Not localized'}"/>
<TextBlock Text="{Tr 'SayHello', LanguageId='fr'}"/> In general use XML escape to escape special characters. For single quote use <!-- textId can be automatically calculate (with x:Name and the context of the element) -->
<Label x:Name="lbMyLabel" >
<Label.Content>
<Tr DefaultText="Text with a ' here" />
</Label.Content>
</Label> To Translate with Bindings <!-- To use the Binding as flexible TextId -->
<TextBlock Text="{Tr {Binding MyPropertyAsTextId}, DefaultText='Not localized'}"/>
<!-- or -->
<TextBlock Text="{Tr TextIdBinding={Binding MyPropertyAsTextId}, DefaultText='Not localized'}"/>
<!-- or -->
<TextBlock Text="{Binding MyPropertyAsTextId, Converter={TrTextIdConverter DefaultText='Not localized'}"/>
<!-- With StringFormat of the TextId (for enum for example) -->
<TextBlock Text="{Tr {Binding MyPropertyAsPartOfTextId}, TextIdStringFormat='MyEnum{0}'}"/>
<!-- or -->
<TextBlock Text="{Tr TextIdBinding={Binding MyPropertyAsPartOfTextId}, TextIdStringFormat='MyEnum{0}'}"/>
<!-- or -->
<TextBlock Text="{Binding MyPropertyAsPartOfTextId, Converter={TrTextIdConverter TextIdStringFormat='MyEnum{0}'}"/>
<!-- To use the Binding as flexible LanguageId -->
<TextBlock Text="{Binding MyPropertyAsLanguageId, Converter={TrLanguageIdConverter TextId='SayHello'}" />
<!-- To use the Binding as a value to inject in the localized text -->
<!-- The translation would be "Hello {0}" or "Bonjour {0}" -->
<TextBlock Text="{Tr SayHello, {Binding FirstName}}" />
<!-- or -->
<TextBlock Text="{Tr SayHello, StringFormatArgBinding={Binding FirstName}}" />
<!-- or -->
<TextBlock Text="{Binding FirstName, Converter={TrStringFormatConverter TextId='SayHello'}" />
<!-- The translation would be "Hello {0} {1}" or "Bonjour {0} {1}" -->
<TextBlock Text="{Tr SayHello, {Binding FirstName}, {Binding LastName}}" />
<!-- or -->
<TextBlock>
<TextBlock.Text>
<Tr TextId="SayHello">
<Tr.StringFormatArgsBindings>
<Binding Path="FirstName" />
<Binding Path="LastName" />
</Tr.StringFormatArgBinding>
</Tr>
</TextBlock.Text>
</TextBlock>
<!-- or -->
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{TrStringFormatMultiValuesConverter TextId='SayHello'}">
<Binding Path="FirstName" />
<Binding Path="LastName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
To concatenate some translations <TextBlock>
<TextBlock.Text>
<MultiTr>
<Tr TextId=TextId1 />
<Tr TextId=TextId2 />
<!-- ... -->
</MultiTr>
</TextBlock.Text>
</TextBlock>
<!-- or simpler syntax -->
<TextBlock Text="{MultiTr {Tr TextId1}, {Tr TextId2}}" />
<!-- or even simpler -->
<TextBlock Text="{MultiTr TextId1, TextId2}" />
<!-- To specify the way it concatenate (by default separate by a space) -->
<TextBlock Text="{MultiTr TextId1, TextId2, Separator=' - '}" />
<!-- or -->
<TextBlock Text="{MultiTr TextId1, TextId2, StringFormat='{0}, {1}.'}" /> Remark : By default the translation made in the XAML are automatically updated when current language changed. To Change the current language from the xaml <!-- to add in the root tag of the xaml file :
xmlns:loc="clr-namespace:Localization;assembly=Localization" -->
<ComboBox ItemsSource="{Binding AvailableLanguages, Source={x:Static loc:Loc.Instance}}"
SelectedItem="{Binding CurrentLanguage, Source={x:Static loc:Loc.Instance}}"/>
Use it In ViewModel (Fody) :You can use the Property attibute public class LocalizedWithFodyClass : INotifyPropertyChanged
{
[Localize]
public string TestProperty => Loc.Tr("TestLabel");
[Localize(nameof(TextIdInAttribute))]
public string TextIdInAttribute { get; set; }
// ...
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} The specific code is injected at compile time thanks to Fody.
It is compatible with PropertyChanged.Fody or other similar fody addins like ReactiveUI.Fody. Just ensure that CodingSebLocalization is defined after in the <?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<PropertyChanged />
<!-- or -->
<ReactiveUI />
<!-- ... -->
<CodingSebLocalization />
</Weavers> OK But... ...How I define my translations ?JsonFileLoaderWith the default JsonFileLoader, Translations are defined in JSON files with the extension "*.loc.json". Here an example : {
"LanguageName": {
"en": "English",
"es": "Español",
"fr": "Français"
},
"[Localization.Examples.MainWindow].lblCurrentLanguage[Label].Content": {
"en": "Current language",
"es": "Lenguaje actual",
"fr": "Langue courrante"
},
"[Localization.Examples.MainWindow].lblHelloInCurrentLanguage[Label].Content": {
"en": "Hello",
"es": "Hola",
"fr": "Bonjour"
},
"HelloInCurrentLanguage": {
"en": "Hello in the current language",
"es": "Hola en la lengua actual",
"fr": "Bonjour dans la langue actuelle"
},
"[Localization.Examples.MainWindow].lblHelloInCurrentLanguage[Label].ToolTip": {
"en": "In english",
"es": "En español",
"fr": "En français"
}
} It's also possible to create a hierarchy : {
"AppName": {
"MainMenu": {
"FileMenuItem": {
"Header": {
"en": "_File",
"fr": "_Fichier"
},
"NewMenuItem": {
"Header": {
"en": "_New",
"fr": "_Nouveau"
}
},
"OpenMenuItem": {
"Header": {
"en": "_Open",
"fr": "_Ouvrir"
}
},
"..."
}
}
} To use like this : Loc.Tr("AppName.MainMenu.FileMenuItem.Header");
Loc.Tr("AppName.MainMenu.FileMenuItem.NewMenuItem.Header");
Loc.Tr("AppName.MainMenu.FileMenuItem.OpenMenuItem.Header"); or like this in XAML : <Menu>
<MenuItem Header="{Tr 'AppName.MainMenu.FileMenuItem.Header', DefaultText='_File'}">
<MenuItem Header="{Tr 'AppName.MainMenu.FileMenuItem.NewMenuItem.Header', DefaultText='_New'}"
Command="ApplicationCommands.New" />
<MenuItem Header="{Tr 'AppName.MainMenu.FileMenuItem.OpenMenuItem.Header', DefaultText='_Open'}"
Command="ApplicationCommands.Open" />
<!-- ... -->
And to load these files : using CodingSeb.Localization.Loaders;
// You need first to add the specific fileLoader
LocalizationLoader.Instance.FileLanguageLoaders.Add(new JsonFileLoader());
// ...
// And then you can add your localization file
LocalizationLoader.Instance.AddFile(@"PathToTheFile\Example1.loc.json");
// or load directly a directory with multiple "*.loc.json" files.
LocalizationLoader.Instance.AddDirectory(@"PathToTheDirectory"); So you can change the text of your app or translate it in a new language without recompile all your application. // or you can also load a translation by code (textId, languageId, value)
LocalizationLoader.Instance.AddTranslation("SayHello", "en", "Hello" );
LocalizationLoader.Instance.AddTranslation("SayHello", "es", "Hola" );
LocalizationLoader.Instance.AddTranslation("SayHello", "fr", "Bonjour" ); YamlFileLoaderFor Yaml format of localization files "*.loc.yaml" it's working the same way as the Json Implement your own file formatIf you want to support an other format than json or yaml, you can create your custom FileLanguageLoader. Simply create a class that implement the ILocalizationFileLoader interface and add an instance of your class in the LocalizationLoader : LocalizationLoader.Instance.FileLanguageLoaders.Add(new YouCustomClassImplementingILocalizationFileLoader()); Find Missing TranslationsYou can activate an option to be notify when a translation is missing. // with all TextId and LanguageId that are missing when you trying to translate them.
Loc.Instance.LogOutMissingTranslations = true;
Loc.Instance.MissingTranslationFound += Loc_MissingTranslationFound; If you want to log it automatically in a json file you can also use the class JsonMissingTranslationsLogger.EnableLogFor(Loc.Instance); Tr and WPF StylesThe |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论