WordPress database error: [INSERT, UPDATE command denied to user '51213-2'@'10.10.20.62' for table 'wp_options']
INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_transient_doing_cron', '1714224046.1900470256805419921875', 'yes') ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)


Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372

Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/rest-api/class-wp-rest-server.php on line 1372
{"id":835,"date":"2011-11-22T16:38:12","date_gmt":"2011-11-22T15:38:12","guid":{"rendered":"http:\/\/www.jonathanantoine.com\/?p=835"},"modified":"2011-11-23T11:59:24","modified_gmt":"2011-11-23T10:59:24","slug":"how-to-bind-an-itemscontrol-to-an-enum-with-localized-descriptions","status":"publish","type":"post","link":"http:\/\/www.jonathanantoine.com\/2011\/11\/22\/how-to-bind-an-itemscontrol-to-an-enum-with-localized-descriptions\/","title":{"rendered":"How to bind an ItemsControl to an Enum with localized descriptions"},"content":{"rendered":"

\"\"Today, it’s a blog on a tip to use the values of an enum as the source of an ItemsControl (ListBox, ComboBox, ListView, etc.) and display them nicely using attributes.<\/p>\n

We’ll provide a localized description to be displayed and the value will still be available to the binding.<\/strong><\/p>\n

In this post we’ll discover two very similar but differents solutions to this common issue.
\n<\/p>\n

[table-of-content]<\/p>\n

Foundations<\/h3>\n

The foundation of the solution is based on reflection.
\nFor a provided type, the RetrieveFromCacheOrAddIt method read the Display attributes and create a list of tuples from it.<\/strong> A cache is created so the reflection is done only once by type.<\/p>\n

The first item (Item1) of the tuple is the real value and the second item (Item2) is the text to be displayed. If the attribute is not found, then the value of the enum is used as a description.<\/p>\n

The display attribute can be found in the System.ComponentModel.DataAnnotations.dll assembly.<\/p>\n

[csharp]
\n\/\/The cache to use
\nprivate readonly Dictionary<Type, List<Tuple<Object, Object>>>
\n _cache = new Dictionary<Type, List<Tuple<Object, Object>>>();<\/p>\n

\/\/The method which fill the cache.
\n private object RetrieveFromCacheOrAddIt(Type type)
\n {
\n \/\/if it is not already in cache
\n if (!this._cache.ContainsKey(type))
\n {
\n \/\/get the fields of the type via reflection
\n var fields = type.GetFields().Where(field => field.IsLiteral);
\n var values = new List<Tuple<Object, Object>>();
\n foreach (var field in fields)
\n {
\n \/\/retrieve the display attributes of the fields
\n var a = (DisplayAttribute[])field
\n .GetCustomAttributes(typeof(DisplayAttribute), false);
\n var valueOfField = field.GetValue(type);<\/p>\n

\/\/if there is a display attribute on the field.
\n if (a.Length > 0)
\n {
\n var newTuple1 =
\n new Tuple<Object, Object>(valueOfField, a[0].GetName());
\n values.Add(newTuple1);
\n }
\n \/\/if not, use the value
\n else
\n {
\n var newTuple =
\n new Tuple<Object, Object>(valueOfField, valueOfField);
\n values.Add(newTuple);
\n }
\n }
\n this._cache[type] = values;
\n }<\/p>\n

return this._cache[type];
\n }[\/csharp]<\/p>\n

Here is an example of an enum with the correct DisplayAttributes set:
\n[csharp] public enum MyEnum
\n {
\n [Display(Name = "My fist name to display")]
\n ValueOne,<\/p>\n

[Display(Name = "My second name to display")]
\n ValueTwo,<\/p>\n

[Display(Name = "My third name to display")]
\n ValueThird,<\/p>\n

ValueFourWithNoDisplayAttribute
\n }[\/csharp]<\/p>\n

Use a converter<\/h3>\n

The first idea which comes in our WPF developer brain is to use a converter. This is easy to implement and pretty classic.
\n<\/strong>
\nHere is the codeof the converter and the regarding XAML usage.
\n[csharp] public object Convert(object value, Type targetType,
\n object parameter, System.Globalization.CultureInfo culture)
\n {
\n var type = value as Type;
\n return type == null ? null : RetrieveFromCacheOrAddIt(type);
\n }[\/csharp]<\/p>\n

The converter is defined in a resource scope available to the binding and the Type of the enum is provided by setting the Source property of the binding to the target enum type using the x:Type markup extension. Here is an example:
\n[xml]
\n<DockPanel Margin="10">
\n <DockPanel.Resources>
\n <local:EnumToDictionnaryConverter x:Key="EnumToDictionnaryConverter" \/>
\n <\/DockPanel.Resources>
\n <TextBlock DockPanel.Dock="Left" Text="First solution : " FontWeight="Bold" \/>
\n <ComboBox DisplayMemberPath="Item2" SelectedValuePath="Item1"
\n SelectedValue="{Binding MyPropertyOnTheViewModel}"
\n ItemsSource="{Binding Source={x:Type local:MyEnum},
\n Converter={StaticResource EnumToDictionnaryConverter}}" \/>
\n<\/DockPanel>[\/xml]<\/p>\n

Use a markup extension<\/h3>\n

The second idea, really less verbose, is to create a markup extension. The type of the enum will be provided as a parameter.<\/strong><\/p>\n

Here is the code of the extension and the XAML usage of it below.
\n[csharp] public class EnumToDictionnaryExtension : MarkupExtension
\n {
\n public Type TargetEnum { get; set; }
\n public EnumToDictionnaryExtension(Type type) { TargetEnum = type; }<\/p>\n

public override object ProvideValue(IServiceProvider serviceProvider)
\n {
\n var type = TargetEnum;
\n if (type == null) return null;
\n return RetrieveFromCacheOrAddIt(type);
\n }<\/p>\n

\/\/RetrieveFromCacheOrAddIt snippet from above !
\n}[\/csharp]<\/p>\n

DisplayMemberPath and SelectedValuePath still need to be set but there is no converter to define and unusual binding source to use.
\n[xml]
\n<ComboBox DisplayMemberPath="Item2" SelectedValuePath="Item1"
\n ItemsSource="{local:EnumToDictionnary {x:Type local:MyEnum}}" \/>[\/xml]<\/p>\n

Localisation – i18n<\/h3>\n

If you want to localize the used text, you can provide the type of a resource file to use. <\/strong>
\nThe Display attribute GetName method will automatically pull the value from the resource file with the ‘name’ key of the attribute.<\/p>\n

For example if I change the previous enum to the definition below, I will have to create a resource file (Localized.resx) and add values for the keys ‘Value1’, ‘Value2’ and ‘Value3’.
\n[csharp]public enum MyEnum
\n{
\n [Display(Name = "Value1", ResourceType = typeof(Localized))]
\n ValueOne,<\/p>\n

[Display(Name = "Value2", ResourceType = typeof(Localized))]
\n ValueTwo,<\/p>\n

[Display(Name = "Value3", ResourceType = typeof(Localized))]
\n ValueThird,<\/p>\n

}[\/csharp]
\nThen I can also create an another resource file named Localized.fr-FR.resx and translate the description in french.
\n\"\"<\/a><\/p>\n

If I set the culture of the UI thread to french, the values will be translated in it. Tada !
\n[csharp]Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");[\/csharp]
\n
\"\"<\/a><\/p>\n

Demo<\/h3>\n

I created a little demo which you can find in my DropBox folder<\/a>. It presents the two solutions. As you can see in the screenshot below, if no display attribute is set, the value of the enum is used:
\n
\"\"<\/a><\/p>\n

[\/table-of-content]<\/p>\n","protected":false},"excerpt":{"rendered":"

Today, it’s a blog on a tip to use the values of an enum as the source of an ItemsControl (ListBox, ComboBox, ListView, etc.) and display them nicely using attributes. We’ll provide a localized description…<\/p>\n","protected":false},"author":3,"featured_media":863,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6,4,5],"tags":[22,14,15,20],"_links":{"self":[{"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/posts\/835"}],"collection":[{"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/comments?post=835"}],"version-history":[{"count":25,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/posts\/835\/revisions"}],"predecessor-version":[{"id":886,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/posts\/835\/revisions\/886"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/media\/863"}],"wp:attachment":[{"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/media?parent=835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/categories?post=835"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.jonathanantoine.com\/wp-json\/wp\/v2\/tags?post=835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}