{"id":21129481,"url":"https://github.com/guorg/gu.localization","last_synced_at":"2025-12-17T01:08:40.987Z","repository":{"id":22705462,"uuid":"26049497","full_name":"GuOrg/Gu.Localization","owner":"GuOrg","description":null,"archived":false,"fork":false,"pushed_at":"2023-12-25T16:16:04.000Z","size":5362,"stargazers_count":73,"open_issues_count":21,"forks_count":14,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-30T19:11:30.097Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GuOrg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2014-11-01T12:00:13.000Z","updated_at":"2025-01-20T02:48:17.000Z","dependencies_parsed_at":"2023-12-14T10:57:16.753Z","dependency_job_id":"44dc4944-94b6-42e1-a1a2-916d8bd2d1ec","html_url":"https://github.com/GuOrg/Gu.Localization","commit_stats":{"total_commits":965,"total_committers":12,"mean_commits":80.41666666666667,"dds":"0.17823834196891186","last_synced_commit":"01f65a79dd36245bdbd5ee77478ee24e64ae81f2"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GuOrg%2FGu.Localization","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GuOrg%2FGu.Localization/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GuOrg%2FGu.Localization/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GuOrg%2FGu.Localization/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GuOrg","download_url":"https://codeload.github.com/GuOrg/Gu.Localization/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247557767,"owners_count":20958047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-20T05:23:09.029Z","updated_at":"2025-12-17T01:08:40.929Z","avatar_url":"https://github.com/GuOrg.png","language":"C#","readme":"# Gu.Localization.\n\n[![Join the chat at https://gitter.im/JohanLarsson/Gu.Localization](https://badges.gitter.im/JohanLarsson/Gu.Localization.svg)](https://gitter.im/JohanLarsson/Gu.Localization?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Build status](https://ci.appveyor.com/api/projects/status/ili1qk8amyjmd71t/branch/master?svg=true)](https://ci.appveyor.com/project/JohanLarsson/gu-localization/branch/master)\n[![Build Status](https://dev.azure.com/guorg/Gu.Localization/_apis/build/status/GuOrg.Gu.Localization?branchName=master)](https://dev.azure.com/guorg/Gu.Localization/_build/latest?definitionId=17\u0026branchName=master)\n[![NuGet](https://img.shields.io/nuget/v/Gu.Localization.svg)](https://www.nuget.org/packages/Gu.Localization/)\n[![NuGet](https://img.shields.io/nuget/v/Gu.Wpf.Localization.svg)](https://www.nuget.org/packages/Gu.Wpf.Localization/)\n\n\n# Contents.\n- [Quickstart](#quickstart)\n- [Usage in XAML.](#usage-in-xaml)\n  - [Simple example](#simple-example)\n  - [With converter](#with-converter)\n  - [Bind a localized string.](#bind-a-localized-string)\n  - [Errorhandling.](#errorhandling)\n  - [CurrentCulture.](#currentculture)\n  - [Binding to Culture and Culture in XAML.](#binding-to-culture-and-culture-in-xaml)\n- [Usage in code.](#usage-in-code)\n  - [Translator.](#translator)\n    - [Culture.](#culture)\n    - [Culture.](#culture)\n    - [CurrentCulture.](#currentculture)\n    - [Cultures.](#cultures)\n    - [ErrorHandling.](#errorhandling)\n    - [Translate.](#translate)\n      - [Translate to neutral culture:](#translate-to-neutral-culture)\n      - [Translate to explicit culture:](#translate-to-explicit-culture)\n      - [Override global error handling (throw on error):](#override-global-error-handling-throw-on-error)\n      - [Override global error handling (return info about error):](#override-global-error-handling-return-info-about-error)\n      - [Translate with parameter:](#translate-with-parameter)\n  - [Translator\u0026lt;T\u0026gt;.](#translatort)\n  - [Translation.](#translation)\n  - [GetOrCreate.](#getorcreate)\n  - [StaticTranslation.](#statictranslation)\n- [ErrorHandling.](#errorhandling)\n  - [Global setting](#global-setting)\n  - [ErrorFormats](#errorformats)\n- [Validate.](#validate)\n  - [Translations.](#translations)\n  - [EnumTranslations\u0026lt;T\u0026gt;.](#enumtranslationst)\n  - [TranslationErrors](#translationerrors)\n  - [Format](#format)\n- [FormatString.](#formatstring)\n  - [IsFormatString](#isformatstring)\n  - [IsValidFormatString](#isvalidformatstring)\n- [LanguageSelector](#languageselector)\n  - [AutogenerateLanguages](#autogeneratelanguages)\n  - [Explicit languages.](#explicit-languages)\n- [Examples](#examples)\n  - [Simple ComboBox language select.](#simple-combobox-language-select)\n  - [ComboBox Language selector](#combobox-language-selector)\n  - [CultureToFlagPathConverter](#culturetoflagpathconverter)\n- [Embedded resource files (weaving)](#embedded-resource-files-weaving)\n  - [Weaving Setup](#weaving-setup)\n- [Analyzer](#analyzer)\n\n\n# Quickstart\n1. `PM\u003e Install-Package Gu.Wpf.Localization` or search for `Gu.Wpf.Localization` in the `Manage NuGet Packages` tab.\n2. Create a new resource from `Project \u003e Properties \u003e Resources` and name it `Resources.\u003ctag\u003e.resx`.\n      Example: `Resources.ru-RU.resx`\n      To see all convention tags you can check them [here](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c)\n3. Use the markup extension like this:\n\n```xaml\n\u003cWindow\n    x:Class=\"WpfApp1.MainWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:localize=\"http://gu.se/Localization\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:properties=\"clr-namespace:WpfApp1.Properties\"\n    Title=\"MainWindow\"\n    mc:Ignorable=\"d\"\u003e\n    \u003cGrid\u003e\n        \u003cGrid.ColumnDefinitions\u003e\n            \u003cColumnDefinition Width=\"Auto\" /\u003e\n            \u003cColumnDefinition Width=\"*\" /\u003e\n        \u003c/Grid.ColumnDefinitions\u003e\n        \u003clocalize:LanguageSelector AutogenerateLanguages=\"True\" /\u003e\n        \u003cTextBlock Grid.Column=\"1\" Text=\"{localize:Static properties:Resources.Some_text}\" /\u003e\n    \u003c/Grid\u003e\n\u003c/Window\u003e\n```\n\nRenders:\n\n![Localize](https://user-images.githubusercontent.com/1640096/61053560-1288a600-a3ee-11e9-9939-930dfa4d911f.gif)\n\n`Text=\"{localize:Static properties:Resources.Some_text}\"` will be the translated text based on the current culture.\n\n**Note**: If you get errors about missing `localize:Static` when adding this, `clean` and `rebuild` your solution from `Build \u003e Clean Solution` and `Build \u003e Rebuild Solution` respectively.\n\n\n**Note**: To set the translation programmatically write: `Translator.Culture = CultureInfo.GetCultureInfo(\"ru-RU\");`\n    To use a neutral language (aka Resources.resx), simply add `[assembly:NeutralResourcesLanguageAttribute(\"en\")]` in your `AssemblyInfo.cs` file found in your project.\n\n\n**Note**: Make sure to add `xmlns:properties=\"clr-namespace:YourApp.Properties\"` and `xmlns:localize=\"http://gu.se/Localization\"` in your xaml.\n\n\n**Note**: Intsall `Gu.Wpf.Localization` in the application project. The library is split in `Gu.Wpf.Localization` and `Gu.Localization` so that usage in domain projects does not require adding WPF dependencies.\n\n\nFor working with resx in Visual Studio [ResXManager](https://marketplace.visualstudio.com/items?itemName=TomEnglert.ResXManager) is a nice extension.\n\n# NeutralResourcesLanguage\n\nAdding:\n```cs\n[assembly:NeutralResourcesLanguage(\"en\")]\n```\n\nTo `AsseblyInfo.cs` or anywhere else tells Gu.Localization what language to use for the neutral resource. It prevents some duplication.\nSee: [NeutralResourcesLanguageAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.resources.neutralresourceslanguageattribute?view=netframework-4.8)\n\n# Usage in XAML.\n\nThe library has a `StaticExtension` markupextension that is used when translating.\nThe reason for naming it `StaticExtension` and not `TranslateExtension` is that Resharper provides intellisense when named `StaticExtension`\nBinding the text like below updates the text when `Translator.CurrentCulture`changes enabling runtime selection of language.\n\nThe markupextension has ErrorHandling = ErrorHandling.ReturnErrorInfoPreserveNeutral as default, it encodes errors in the result, see [ErrorFormats](#3-errorhandling))\n\n## Simple example\nFor each language, create a resource.xx.resx file. You can use [ResXManager](https://marketplace.visualstudio.com/items?itemName=TomEnglert.ResXManager#overview) to do this for you.\n\n```xaml\n\u003cUserControl ...\n             xmlns:l=\"clr-namespace:Gu.Wpf.Localization;assembly=Gu.Wpf.Localization\"\n             xmlns:p=\"clr-namespace:AppNamespace.Properties\"\n             xmlns:local=\"clr-namespace:YourNamespace;assembly=Gu.Localization\"\u003e\n    ...\n    \u003c!-- Dropbownbox to select a language --\u003e\n    \u003cComboBox x:Name=\"LanguageComboBox\"\n              ItemsSource=\"{Binding Path=(localization:Translator.Cultures)}\"\n              SelectedItem=\"{Binding Path=(localization:Translator.Culture),\n                                              Converter={x:Static l:CultureOrDefaultConverter.Default}}\" /\u003e\n\n    \u003c!-- Label that changes translation upon language selection --\u003e\n    \u003cLabel Content=\"{l:Static p:Resources.ResourceKeyName}\" /\u003e\n```\n\n## With converter\n\nWhen `StaticExctension` is used for setting `Binding.Source` it returns an `ITranslation`, this means it can be used with a converter like below.\n\n```xaml\n\u003cTextBlock Text=\"{Binding Source={l:Static p:Resources.TranslatedToAll}, Path=Translated, Converter={x:Static local:StringToUpperConverter.Default}}\" /\u003e\n```\n\n```c#\n[ValueConversion(typeof(string), typeof(string))]\npublic sealed class StringToUpperConverter : IValueConverter\n{\n    public static readonly StringToUpperConverter Default = new StringToUpperConverter();\n\n    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)\n    {\n        return value switch\n        {\n            string { } s =\u003e s.ToUpper(culture),\n            null =\u003e null,\n            _ =\u003e throw new ArgumentException($\"Expected a string, was: {value.GetType()} with value: {value}\"),\n        };\n    }\n\n    object IValueConverter.ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)\n    {\n        throw new System.NotSupportedException($\"{nameof(StringToUpperConverter)} can only be used in OneWay bindings\");\n    }\n}\n```\n\n## Bind a localized string.\n\n```xaml\n\u003cWindow ...\n        xmlns:p=\"clr-namespace:Gu.Wpf.Localization.Demo.WithResources.Properties\"\n        xmlns:l=\"http://gu.se/Localization\"\u003e\n    ...\n    \u003cTextBlock Text=\"{l:Static p:Resources.SomeResource}\" /\u003e\n    \u003cTextBlock Text=\"{l:Enum ResourceManager={x:Static p:Resources.ResourceManager},\n                             Member={x:Static local:SomeEnum.SomeMember}}\" /\u003e\n    ...\n```\n\nThe above will show SomeResource in the `Translator.CurrentCulture` and update when culture changes.\n\n## Errorhandling.\nBy setting the attached property `ErrorHandling.Mode` we override how translation errors are handled by the `StaticExtension` for the child elements.\nWhen null the `StaticExtension` uses ReturnErrorInfoPreserveNeutral\n```xaml\n\u003cGrid l:ErrorHandling.Mode=\"ReturnErrorInfo\"\n     ...   \u003e\n    ...\n    \u003cTextBlock Text=\"{l:Static p:Resources.SomeResource}\" /\u003e\n    \u003cTextBlock Text=\"{l:Enum ResourceManager={x:Static p:Resources.ResourceManager},\n                             Member={x:Static local:SomeEnum.SomeMember}}\" /\u003e\n    ...\n```\n\n## CurrentCulture.\nA markupextension for accessing `Translator.CurrentCulture` from xaml. Retruns a binding that updates when CurrentCulture changes.\n\n```xaml\n\u003cGrid numeric:NumericBox.Culture=\"{l:CurrentCulture}\"\n     ...   \u003e\n    ...\n        \u003cStackPanel Orientation=\"Horizontal\"\u003e\n            \u003cTextBlock Text=\"Effective culture: \" /\u003e\n            \u003cTextBlock Text=\"{l:CurrentCulture}\" /\u003e\n        \u003c/StackPanel\u003e\n    ...\n```\n\n## Binding to Culture and Culture in XAML.\nThe static properties support binding. Use this XAML for a twoway binding:\n```xaml\n\u003cWindow ...\n        xmlns:localization=\"clr-namespace:Gu.Localization;assembly=Gu.Localization\"\u003e\n    ...\n\u003cTextBox Text=\"{Binding Path=(localization:Translator.Culture)}\" /\u003e\n```\n\n# Usage in code.\n\nThe API is not super clean, introducing a helper like this can clean things up a bit.\n\nCreating it like the above is pretty verbose. Introducing a helper like below can clean it up some.\nThe analyzer checks calls to this method but it assumes:\n1. That the class is named `Translate`\n2. That the namespace the class is in has a class named `Resources`\n3. That the first argument is of type `string`.\n4. That the return type is `string` or `ITranslation`\n\n```c#\nnamespace YourNamespace.Properties\n{\n    using Gu.Localization;\n    using Gu.Localization.Properties;\n\n    public static class Translate\n    {\n        /// \u003csummary\u003eCall like this: Translate.Key(nameof(Resources.Saved_file__0_)).\u003c/summary\u003e\n        /// \u003cparam name=\"key\"\u003eA key in Properties.Resources\u003c/param\u003e\n        /// \u003cparam name=\"errorHandling\"\u003eHow to handle translation errors like missing key or culture.\u003c/param\u003e\n        /// \u003creturns\u003eA translation for the key.\u003c/returns\u003e\n        public static string Key(string key, ErrorHandling errorHandling = ErrorHandling.ReturnErrorInfoPreserveNeutral)\n        {\n            return TranslationFor(key, errorHandling).Translated;\n        }\n\n        /// \u003csummary\u003eCall like this: Translate.Key(nameof(Resources.Saved_file__0_)).\u003c/summary\u003e\n        /// \u003cparam name=\"key\"\u003eA key in Properties.Resources\u003c/param\u003e\n        /// \u003cparam name=\"errorHandling\"\u003eHow to handle translation errors like missing key or culture.\u003c/param\u003e\n        /// \u003creturns\u003eA translation for the key.\u003c/returns\u003e\n        public static ITranslation TranslationFor(string key, ErrorHandling errorHandling = ErrorHandling.ReturnErrorInfoPreserveNeutral)\n        {\n            return Gu.Localization.Translation.GetOrCreate(Resources.ResourceManager, key, errorHandling);\n        }\n    }\n}\n```\n\n## Translator.\n\n### Culture.\nGet or set the current culture. The default is `null`\nChanging culture updates all translations. Setting culture to a culture for which there is no translation throws. Check ContainsCulture() first.\n\n### Culture.\nGet or set the current culture. The default is `null`\nChanging culture updates all translations. Setting culture to a culture for which there is no translation throws. Check ContainsCulture() first.\n\n### CurrentCulture.\nGet the culture used in translations. By the following mechanism:\n  1) CurrentCulture if not null.\n  2) Any Culture in \u003csee cref=\"Cultures\"/\u003e matching \u003csee cref=\"CultureInfo.CurrentCulture\"/\u003e by name.\n  3) Any Culture in \u003csee cref=\"Cultures\"/\u003e matching \u003csee cref=\"CultureInfo.CurrentCulture\"/\u003e by name.\n  4) CultureInfo.InvariantCulture\nWhen this value changes CurrentCultureChanged is raised and all translatins updates and notifies.\n\n### Cultures.\nGet a list with the available cultures. Cultures are found by looking in current directory and scanning for satellite assemblies.\n\n### ErrorHandling.\nGet or set how errors are handled. The default value is `ReturnErrorInfoPreserveNeutral`.\n\n### Translate.\nTranslate a key in a ResourceManager.\n\nUse global culture \u0026 error handling:\n```c#\nTranslator.Culture = CultureInfo.GetCultureInfo(\"en\"); // no need to set this every time, just for illustration purposes here.\nstring inEnglish = Translator.Translate(Properties.Resources.ResourceManager,\n                                        nameof(Properties.Resources.SomeResource));\n```\n\n#### Translate to neutral culture:\n```c#\nstring neutral = Translator.Translate(Properties.Resources.ResourceManager,\n                                      nameof(Properties.Resources.SomeResource),\n                                      CultureInfo.InvariantCulture);\n```\n\n#### Translate to explicit culture:\n```c#\nstring inSwedish = Translator.Translate(Properties.Resources.ResourceManager,\n                                        nameof(Properties.Resources.SomeResource),\n                                        CultureInfo.GetCultureInfo(\"sv\"));\n```\n\n#### Override global error handling (throw on error):\n```c#\nTranslator.ErrorHandling = ErrorHandling.ReturnErrorInfo; // no need to set this every time, just for illustration purposes here.\nstring inSwedish = Translator.Translate(Properties.Resources.ResourceManager,\n                                        nameof(Properties.Resources.SomeResource),\n                                        ErrorHandling.Throw);\n```\n\n#### Override global error handling (return info about error):\n```c#\nTranslator.ErrorHandling = ErrorHandling.Throw; // no need to set this every time, just for illustration purposes here.\nstring inSwedish = Translator.Translate(Properties.Resources.ResourceManager,\n                                        nameof(Properties.Resources.SomeResource),\n                                        ErrorHandling.ReturnErrorInfo);\n```\n\n#### Translate with parameter:\n```c#\nTranslator.Culture = CultureInfo.GetCultureInfo(\"en\");\nstring inSwedish = Translator.Translate(Properties.Resources.ResourceManager,\n                                        nameof(Properties.Resources.SomeResource__0__),\n                                        foo);\n```\n\n### MissingTranslation.\nAn event that notifies when the key or culture is missing. Can be used for logging.\n\n```cs\nTranslator.MissingTranslation += (sender, args) =\u003e Log($\"Missing translation for {args.Key} when translating to {args.Language}.\");\n```\n\n## Translator\u0026lt;T\u0026gt;.\n\nSame as translator but used like `Translator\u003cProperties.Resources\u003e.Translate(...)`\n\n## Translation.\nAn object with a Translated property that is a string with the value in `Translator.CurrentCulture`\nImplements `INotifyPropertyChanged` and notifies when for the property `Translated` if a change in `Translator.CurrentCulture` updates the translation.\n\n## GetOrCreate.\nReturns an `ITranslation` from cache or creates and caches a new instance.\nIf ErrorHandling is Throw it throws if the key is missing. If other than throw a `StaticTranslation` is returned.\n\n```c#\nTranslation translation = Translation.GetOrCreate(Properties.Resources.ResourceManager, nameof(Properties.Resources.SomeResource))\n```\n\n## StaticTranslation.\nAn implementation of `ITranslation` that never updates the `Translated`property and returns the value of `Translated` when calling `Translate()`on it with any paramaters.\nThis is returned from `Translation.GetOrCreate(...)` if the key is missing.\n\n# ErrorHandling.\nWhen calling the translate methods an ErrorHandling argument can be provided.\nIf `ErrorHandling.ReturnErrorInfo` is passed in the method does not throw but returns information about the error in the string.\nThere is also a property `Translator.ErrorHandling` that sets default behaviour. If an explicit errorhandling is passed in to a method it overrides the global setting.\n\n## Global setting\nBy setting `Translator.Errorhandling` the global default is changed.\n\n## ErrorFormats\nWhen `ReturnErrorInfo` or `ReturnErrorInfoPreserveNeutral` is used the following formats are used to encode errors.\n\n| Error               |         Format          |\n|---------------------|:-----------------------:|\n| missing key         |        `!{key}!`        |\n| missing culture     |        `~{key}~`        |\n| missing translation |        `_{key}_`        |\n| missing resources   |        `?{key}?`        |\n| invalid format      |`{{\"{format}\" : {args}}}`|\n| unknown error       |    `#{key}#`            |\n\n\n# Validate.\nConveience API for unit testing localization.\n\n## Translations.\n\nValidate a `ResourceManager` like this:\n```c#\nTranslationErrors errors = Validate.Translations(Properties.Resources.ResourceManager);\nAssert.IsTrue(errors.IsEmpty);\n```\n\nChecks:\n- That all keys has a non null value for all cultures in `Translator.AllCultures`\n- If the resource is a format string like `\"First: {0}, second{1}\"` it checks that.\n  - The number of format items are the same for all cultures.\n  - That all format strings has format items numbered 0..1..n\n\n## EnumTranslations\u0026lt;T\u0026gt;.\nValidate an `enum` like this:\n```c#\nTranslationErrors errors = Validate.EnumTranslations\u003cDummyEnum\u003e(Properties.Resources.ResourceManager);\nAssert.IsTrue(errors.IsEmpty);\n```\nChecks:\n- That all enum members has keys in the `ResourceManager`\n- That all keys has non null value for all cultures in `Translator.AllCultures`\n\n## TranslationErrors\n`errors.ToString(\"  \", Environment.NewLine);`\nPrints a formatted report with the errors found, sample:\n\n```\nKey: EnglishOnly\n  Missing for: { de, sv }\nKey: Value___0_\n  Has format errors, the formats are:\n    Value: {0}\n    null\n    Värde: {0} {1}\n```\n## Format\nValidate a formatstring like this:\n```c#\nValidate.Format(\"Value: {0}\", 1);\n```\n\n```c#\nDebug.Assert(Validate.IsValidFormat(\"Value: {0}\", 1), \"Invalid format...\");\n```\n\n# FormatString.\nConveience API for testing formatstrings.\n\n## IsFormatString\nReturns true if the string contains placeholders like `\"Value: {0}\"` and is a valid format string.\n\n## IsValidFormatString\nReturns true if the string contains placeholders like `\"Value: {0}\"` that matches the number of parameters and is a valid format string.\n\n# LanguageSelector\nA simple control for changing current language.\nA few flags are included in the library, many are probably missing.\n\n***Note: LanguageSelector might be depricated in the future***\n\n## AutogenerateLanguages\nDefault is false.\nIf true it popolates itself with `Translator.Cultures` in the running application and picks the default flag or null.\n\n```xaml\n\u003cl:LanguageSelector AutogenerateLanguages=\"True\" /\u003e\n```\n\n## Explicit languages.\n\n```xaml\n\u003cl:LanguageSelector\u003e\n    \u003cl:Language Culture=\"de-DE\"\n                FlagSource=\"pack://application:,,,/Gu.Wpf.Localization;component/Flags/de.png\" /\u003e\n    \u003cl:Language Culture=\"en-GB\"\n                FlagSource=\"pack://application:,,,/Gu.Wpf.Localization;component/Flags/gb.png\" /\u003e\n    \u003cl:Language Culture=\"sv-SE\"\n                FlagSource=\"pack://application:,,,/Gu.Wpf.Localization;component/Flags/se.png\" /\u003e\n\u003c/l:LanguageSelector\u003e\n```\n\n![screenie](http://i.imgur.com/DKfx8WB.png)\n\n# Examples\n\n## Simple ComboBox language select.\nThe below example binds the available cutures to a ComboBox.\n```xaml\n        \u003cComboBox ItemsSource=\"{Binding Path=(localization:Translator.Cultures)}\" DockPanel.Dock=\"Top\" HorizontalAlignment=\"right\"\n          SelectedItem=\"{Binding Path=(localization:Translator.CurrentCulture)}\"/\u003e\n```\n\n## ComboBox Language selector\n```xaml\n\u003cWindow ...\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:globalization=\"clr-namespace:System.Globalization;assembly=mscorlib\"\n        xmlns:l=\"http://gu.se/Localization\"\n        xmlns:localization=\"clr-namespace:Gu.Localization;assembly=Gu.Localization\"\u003e\n    \u003cGrid\u003e\n        \u003cComboBox MinWidth=\"100\"\n                  HorizontalAlignment=\"Right\"\n                  VerticalAlignment=\"Top\"\n                  ItemsSource=\"{Binding Path=(localization:Translator.Cultures)}\"\n                  SelectedItem=\"{Binding Path=(localization:Translator.Culture)}\"\u003e\n            \u003cComboBox.ItemTemplate\u003e\n                \u003cDataTemplate DataType=\"{x:Type globalization:CultureInfo}\"\u003e\n                    \u003cGrid\u003e\n                        \u003cGrid.ColumnDefinitions\u003e\n                            \u003cColumnDefinition Width=\"Auto\" /\u003e\n                            \u003cColumnDefinition Width=\"Auto\" /\u003e\n                        \u003c/Grid.ColumnDefinitions\u003e\n\n                        \u003cImage Grid.Column=\"0\"\n                               Height=\"12\"\n                               VerticalAlignment=\"Center\"\n                               Source=\"{Binding Converter={x:Static l:CultureToFlagPathConverter.Default}}\"\n                               Stretch=\"Fill\" /\u003e\n\n                        \u003cTextBlock Grid.Column=\"1\"\n                                   Margin=\"10,0,0,0\"\n                                   HorizontalAlignment=\"Left\"\n                                   VerticalAlignment=\"Center\"\n                                   Text=\"{Binding NativeName}\" /\u003e\n                    \u003c/Grid\u003e\n                \u003c/DataTemplate\u003e\n            \u003c/ComboBox.ItemTemplate\u003e\n        \u003c/ComboBox\u003e\n\n        ...\n    \u003c/Grid\u003e\n\u003c/Window\u003e\n```\n\n## CultureToFlagPathConverter\n\nFor convenience a converter that converts from `CultureInfo` to a string with the pack uri of the flag resource is included.\n\n# Embedded resource files (weaving)\n\n_\"Weaving refers to the process of injecting functionality into an existing program.\"_\n\nYou might want to publish your software as just one .exe file, without additional assemblies (dll files). Gu.Localization supports this, and a sample project is added [here](https://github.com/GuOrg/Gu.Localization/tree/master/Gu.Wpf.Localization.Demo.Fody). We advice you to use Fody (for it is tested).\n\n## Weaving Setup\n\n- Install https://www.nuget.org/packages/Fody/ (and add FodyWeavers.xml to your project, see [here](https://github.com/Fody/Fody#add-fodyweaversxml))\n- Install https://www.nuget.org/packages/Costura.Fody/\n- Install https://www.nuget.org/packages/Resource.Embedder/ to include the satelite assemblies _(in the folders /sv-SE/, /nl-NL/, etc)_\n\nYour resource files are now embeded in your executable. Gu.Localization will use the embedded resource files.\n\n# Analyzer\n![animation](https://user-images.githubusercontent.com/1640096/39090329-8115bd4a-45dc-11e8-8cc5-a4af4a2f5812.gif)\n\nChecks if keys exists and some code fixes for conveninence.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguorg%2Fgu.localization","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguorg%2Fgu.localization","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguorg%2Fgu.localization/lists"}