Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
317 views
in Technique[技术] by (71.8m points)

c# - How do I resolve the value of a databinding inside a MarkupExtension?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...