Can my value converter access the target of the binding?

Dear Dr. WPF,

In my application, I’m using a value converter to convert a GUID to a static resource.  The GUID is accessible in my DataTemplate through a binding like this:

<DataTemplate>
  <Grid Height="Auto" Width="Auto">
    <TextBlock Text="{Binding Path=ID}" />
  </Grid>
</DataTemplate>

I would really like to use the GUID in a more dynamic way as a key into a resource dictionary. I imagine it would look something like this (although obviously this won’t work): 

<DataTemplate>
  <Grid Height="Auto" Width="Auto">
    <ContentControl 
        Content="{StaticResource {Binding Path=ID}}" />
  </Grid>
</DataTemplate>

I thought I might be able to use a binding along with a value converter that uses FindResource() to look up the static resource. Unfortunately, my value converter does not receive a reference to the object on which the binding is set. It only gets the bound value (the GUID) and the type of the target dependency property. In order to call FindResource(), I need a reference to the actual target dependency object.

Is there an easy way to do this in WPF?

Thanks for any help you can provide!

Sincerely,
Jim
 


Hi Jim,

Yes, it can be frustrating that your value converter does not receive a reference to the target dependency object for the binding. Value converters were designed to be more generic in nature, allowing them to be used in scenarios that might not involve bindings. As such, they have no knowledge of the binding itself or the object on which it is set. That said, there are actually many cases where a value converter might desire this kind of contextual information. 

Your scenario is a prime candidate for a multibinding and multivalue converter. With a multibinding, you can actually supply your own reference to the target dependency object using one of the bindings, as follows:

<DataTemplate>
  <Grid>
    <ContentControl>
      <ContentControl.Content>
        <MultiBinding Converter="{StaticResource MyConverter}">
          <MultiBinding.Bindings>
            <Binding RelativeSource="{RelativeSource Self}" />
            <Binding Path="ID" />
          </MultiBinding.Bindings>
        </MultiBinding>
      </ContentControl.Content>
    </ContentControl>
  </Grid>
</DataTemplate>

 

In this case, the converter class must implement the IMultiValueConverter interface so that it can be used with the multibinding. Since we have conveniently passed in a Self reference as the first binding, we now have a reference to the target dependency object in our converter. The converter’s Convert method might look something like the following:

public object Convert(object[] values, Type targetType, 
    object parameter, CultureInfo culture)
{
  FrameworkElement targetObject = values[0] as FrameworkElement;
  if (targetObject == null)
  {
    return DependencyProperty.UnsetValue;
  }
  return targetObject.TryFindResource(values[1]);
}

 

I hope this helps!

Best regards,
Dr. WPF

One Response to “Can my value converter access the target of the binding?”

  1. Geish says:

    How could you recover the targetObject in the ConvertBack call?