I've made a markup extension for translating strings based on a key. Example
<TextBlock Text="{Translate myKey}" />
Now I want to be able to use nested bindings for providing my keys. Example:
<TextBlock Text="{Translate {Binding KeyFromDataContext}}" />
When I do this I get a System.Windows.Data.Binding object. By calling ProvideValue and passing down the ServiceProvider I can get a BindingExpression:
var binding = Key as Binding;
if (binding == null) {
return null;
}
var bindingExpression = binding.ProvideValue(_serviceProvider) as BindingExpression;
if (bindingExpression == null) {
return null;
}
var bindingKey = bindingExpression.DataItem;
I can get this bindingExpression, but the DataItem property is null. I've tested my binding like this
<TextBlock Text="{Binding KeyFromDataContext}" />
and it works fine.
Any ideas?
It is not possible to get the value of a binding. You're not supposed to be even trying to do this. WPF uses some fancy reflection to resolve the bindings and trust me - you do not wan't to start trying that yourself.
Anyway with that in mind, this is what I ended up doing, which actually is a nice solution:
I made a TranslateConverter
that took care of the translation:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var key = value as string ?? parameter as string;
if (key != null)
{
// Do translation based on the key
}
return null;
}
Then in my TranslateExtension
I simply do this:
var binding = Key as Binding ?? new Binding{Mode = BindingMode.OneWay};
binding.Converter = new TranslateConverter(_targetObject, _targetProperty, Dictionary, Converter);
binding.ConverterParameter = Key is Binding ? null : Key as string;
return binding.ProvideValue(serviceProvider);
This way a binding is resolved by WPF and is passed to the converter as value, while a simple text-key is passed to the converter as a paramter.
_targetObject
and _targetProperty
are obtained from the ServiceProvider.