Share via


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.)

Comments

  • Anonymous
    February 08, 2014
    Actually, there is a small problem in Your solution. Did you try to use it in templates / styles in Expression Blend designer?Expression Blend is very sensitive in this case. You will get an exception similar to this "There is only supported StaticResource,DynamicResource or classes inherited by BindingBase". But don't worry it is really simple to omit the problem. Inherit your class from Binding and assign binding parts in constructor ;-) It's working for me.
  • Anonymous
    May 22, 2014
    when ServiceProvider.Target is null or somehting like that, ProviderValue must return this ...