Binding to a MarkupExtension that Returns a Binding
Is it possible to bind properties to a MarkupExtension that returns a Binding? Yes! The MarkupExtension just needs to return a BindingExpression by returning binding.ProvideValue(serviceProvider):
[MarkupExtensionReturnType(typeof(BindingExpression))]
public class PhysicalLengthMarkupExtension : MarkupExtension
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
Binding physicalLengthBinding = new Binding();
physicalLengthBinding.Source = _dpiProvider;
physicalLengthBinding.Path = new PropertyPath("DPI");
physicalLengthBinding.Converter = _dpiConverter;
physicalLengthBinding.ConverterParameter = _length;
return physicalLengthBinding.ProvideValue(serviceProvider);
}
}
Which enables the ability to write
<TextBlock Width="{Markup:PhysicalLengthMarkupExtension 3cm}"/>
instead of the more verbose and redundant
<TextBlock>
<TextBlock.Width>
< Binding
Source="{StaticResource DpiProvider}"
Path="DPI"
Converter="{StaticResource DpiConverter}"
ConverterParameter="2in"
/>
</TextBlock.Width>
</TextBlock>
(Btw, I know that WPF takes DPI into account when doing layout calculations but let’s just use it as an example here.)