www.planet-xaml.net
[XAMLWPF]

Using ResourceDictionary Values in ValueConverters

by Florian Krüsch July 12, 2008

Congratulations, Josh, to your 50th article on the Codeproject... that's quite impressive indeed!

I do think, however, there is a much simpler solution in this case, which is truely along the WPF way of things without hackery.

Accessing stuff inside Resource Dictionaries from within a ValueConverter is something I stumbled upon over and over again in XAML. My solution is a combination of MultiBinding and an IMultiConverter. The first Binding resembles the original binding. The second Binding binds to the FrameworkElement that provides the Resource Dictionary scope for the resource.

In this case, I've added the type of the enum as a ConverterParameter for a generic solution:

This is how the Binding looks like:

XAMLtoggle
<ItemsControl x:Name="_personList">
  
<ItemsControl.ItemTemplate>
    
<MultiBinding 
     
Converter="{StaticResource EnumTypeKeyResourceConverter}" 
     
ConverterParameter="{x:Type local:DisplayDetailLevel}"
    
>
      
<Binding Path="Value" ElementName="_detailLevelSlider" />
      
<Binding ElementName="_personList" />                        
    
</MultiBinding>             
  
</ItemsControl.ItemTemplate>
</
ItemsControl>

The code for the ValueConverter is a little bit more, mostly because of the generic number and enum conversion stuff:

C#toggle
public class EnumTypeKeyResourceConverter 
    : IMultiValueConverter
  {
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
      if (values.Length < 2) 
            return Binding.DoNothing;

      Object value = values[0];
      var scope = values[1] as FrameworkElement;
      var enumType = parameter as Type;

      if (scope == null || enumType == null)
            return Binding.DoNothing;

      if (!enumType.IsEnum)
            return Binding.DoNothing;
            
      
// Parse number

      Double d;
      if (!Double.TryParse(System.Convert.ToString(value), out d))
            return Binding.DoNothing;

      
// to int.. 
      Int32 n = System.Convert.ToInt32(Math.Round(d));

      
// to enum
      if ((!Enum.IsDefined(enumType, n)))
            return Binding.DoNothing;

      var key = Enum.ToObject(enumType, n);
      Object resource = scope.TryFindResource(key);

      return resource == null ? Binding.DoNothing : resource;
    }

    public object[] ConvertBack(object value, 
                                Type[] targetTypes, 
                                object parameter,
                                CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Cheers,
Florian

 

No comments

Language | Sprache

All[e]  |  english  |  deutsch
Tags
 

Profile

Florian Kruesch

I am working as a freelance software architect, developer and consultant in Düsseldorf, Germany.

My focus is on Microsoft technologies and .NET 3.0, especially WPF, ASP.net and SQL Server.

I've been a lead programmer on the WPF development of the OTTO Vista Store at SinnerSchrader Studios.

My client list includes DHL, LG and Ogilvy Interactive.