WordPress database error: [INSERT, UPDATE command denied to user '51213-2'@'10.10.20.25' for table 'wp_options']
INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_transient_doing_cron', '1715242845.9572160243988037109375', '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/feed-rss2.php on line 8
converter – Jonathan ANTOINE's thoughts http://www.jonathanantoine.com Yet another blog about... Wed, 23 Nov 2011 10:59:24 +0000 en-US hourly 1 https://wordpress.org/?v=5.5.3 How to bind an ItemsControl to an Enum with localized descriptions http://www.jonathanantoine.com/2011/11/22/how-to-bind-an-itemscontrol-to-an-enum-with-localized-descriptions/ http://www.jonathanantoine.com/2011/11/22/how-to-bind-an-itemscontrol-to-an-enum-with-localized-descriptions/#comments Tue, 22 Nov 2011 15:38:12 +0000 http://www.jonathanantoine.com/?p=835 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 to be displayed and the value will still be available to the binding.

In this post we’ll discover two very similar but differents solutions to this common issue.

[table-of-content]

Foundations

The foundation of the solution is based on reflection.
For a provided type, the RetrieveFromCacheOrAddIt method read the Display attributes and create a list of tuples from it. A cache is created so the reflection is done only once by type.

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.

The display attribute can be found in the System.ComponentModel.DataAnnotations.dll assembly.

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

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

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

return this._cache[type];
}[/csharp]

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

[Display(Name = "My second name to display")]
ValueTwo,

[Display(Name = "My third name to display")]
ValueThird,

ValueFourWithNoDisplayAttribute
}[/csharp]

Use a converter

The first idea which comes in our WPF developer brain is to use a converter. This is easy to implement and pretty classic.

Here is the codeof the converter and the regarding XAML usage.
[csharp] public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
var type = value as Type;
return type == null ? null : RetrieveFromCacheOrAddIt(type);
}[/csharp]

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:
[xml]
<DockPanel Margin="10">
<DockPanel.Resources>
<local:EnumToDictionnaryConverter x:Key="EnumToDictionnaryConverter" />
</DockPanel.Resources>
<TextBlock DockPanel.Dock="Left" Text="First solution : " FontWeight="Bold" />
<ComboBox DisplayMemberPath="Item2" SelectedValuePath="Item1"
SelectedValue="{Binding MyPropertyOnTheViewModel}"
ItemsSource="{Binding Source={x:Type local:MyEnum},
Converter={StaticResource EnumToDictionnaryConverter}}" />
</DockPanel>[/xml]

Use a markup extension

The second idea, really less verbose, is to create a markup extension. The type of the enum will be provided as a parameter.

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

public override object ProvideValue(IServiceProvider serviceProvider)
{
var type = TargetEnum;
if (type == null) return null;
return RetrieveFromCacheOrAddIt(type);
}

//RetrieveFromCacheOrAddIt snippet from above !
}[/csharp]

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

Localisation – i18n

If you want to localize the used text, you can provide the type of a resource file to use.
The Display attribute GetName method will automatically pull the value from the resource file with the ‘name’ key of the attribute.

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’.
[csharp]public enum MyEnum
{
[Display(Name = "Value1", ResourceType = typeof(Localized))]
ValueOne,

[Display(Name = "Value2", ResourceType = typeof(Localized))]
ValueTwo,

[Display(Name = "Value3", ResourceType = typeof(Localized))]
ValueThird,

}[/csharp]
Then I can also create an another resource file named Localized.fr-FR.resx and translate the description in french.

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

Demo

I created a little demo which you can find in my DropBox folder. 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:

[/table-of-content]

]]>
http://www.jonathanantoine.com/2011/11/22/how-to-bind-an-itemscontrol-to-an-enum-with-localized-descriptions/feed/ 6
Convert in code as in XAML: how to get the XAML processor’s converter ? http://www.jonathanantoine.com/2011/09/02/convert-in-code-as-in-xaml-how-to-get-thet-xaml-processors-converter/ http://www.jonathanantoine.com/2011/09/02/convert-in-code-as-in-xaml-how-to-get-thet-xaml-processors-converter/#comments Fri, 02 Sep 2011 08:08:59 +0000 http://www.jonathanantoine.com/?p=160 convert featured imageSometimes you need to set property on controls from the code and then you realize that this is not like in XAML: these are not strings? No, they are not! This is because the XAML processor convert the string to the correct type when it process the XAML. In this post we’ll see how to reproduce the same behavior from the code: a little snippet which can help you someday !

As you can find out on MSDN, everything is done trough the class TypeConverter. For any type, you can create a TypeConverter (to be precise: a class inheriting from TypeConverter) which will convert it from any other type and especially string. Note that there is only four methods used in the XAML processing: CanConvertTo, CanConvertFrom, ConvertTo, ConvertFrom.

When the XAML processor process the XAML it checks, the presence of a TypeConverter attribute on the target property. This attribute simply specify which converter can be used to convert a value from a given type to a value of the aimed property’s type. If it exists, the XAML processor instanciates one and use it to convert to the correct type value.

Here is the snippet, in his simplified version, I use to reproduce the same behavior in code:

[csharp]
public T ConvertTo<T>(string originalString)
{
var typeConverter = TypeDescriptor.GetConverter(typeof(T));
if (typeConverter != null)
return (T)typeConverter.ConvertFromString(originalString);
else
{
var errorMsg = string.Format("Cannot retrive the converter of type{0}",
typeof(T).Name);
throw new ArgumentOutOfRangeException(errorMsg);
}
}

public T ConvertTo<T>(object originalValue)
{
var typeConverter = TypeDescriptor.GetConverter(typeof(T));
if (typeConverter != null)
return (T)typeConverter.ConvertFrom(originalValue);
else
{
var errorMsg = string.Format("Cannot retrive the converter of type{0}",
typeof(T).Name);
throw new ArgumentOutOfRangeException(errorMsg);
}
}
[/csharp]

I can then use it to do the most common thing in XAML: create a SolidColorBrush from a string. You can notice that any representation can be used: hexadecimal, name of the color, etc. :

[csharp]SolidColorBrush redBrush = ConvertTo<SolidColorBrush>("Red");
SolidColorBrush anotherBrush = ConvertTo<SolidColorBrush>("#FF125645");
[/csharp]

This is just an exemple and this snippet can be enhanced with, for example, calls to CanConvertXXX. Also if you want more information on TypeConverter and how to implement a custome one, I recommend you to read the MSDN page which is quite well written on this subject.

Regards,

kick it on DotNetKicks.com

]]>
http://www.jonathanantoine.com/2011/09/02/convert-in-code-as-in-xaml-how-to-get-thet-xaml-processors-converter/feed/ 1