jose
jose

Reputation: 63

Template binding to ScaleTransform not work in Custom Control

I created simple custom control which derive from Control.

This control has 2 DP which I bind in xaml on ScaleTransform.

Code behind.

public class MyControl : Control
{
        public static readonly DependencyProperty ScaleXProperty = DependencyProperty.Register(
        "ScaleX", typeof (double), typeof (MyControl), new FrameworkPropertyMetadata(OnScaleXChanged));

    public static readonly DependencyProperty ScaleYProperty = DependencyProperty.Register(
        "ScaleY", typeof (double), typeof (MyControl), new FrameworkPropertyMetadata(OnScaleYChanged));

                public double ScaleX
    {
        get { return (double) GetValue(ScaleXProperty); }
        set { SetValue(ScaleXProperty, value); }
    }

    public double ScaleY
    {
        get { return (double) GetValue(ScaleYProperty); }
        set { SetValue(ScaleYProperty, value); }
    }
}

XAML.

    <Style TargetType="{x:Type local:MyControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">

                    <Border.LayoutTransform>
                        <ScaleTransform ScaleX="{TemplateBinding ScaleX}" ScaleY="{TemplateBinding ScaleY}" />
                    </Border.LayoutTransform>


                    <Image HorizontalAlignment="Stretch"
                           VerticalAlignment="Stretch"
                           Source="{TemplateBinding Icon}"
                           StretchDirection="Both" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I use MyControl in Window. After I changed ScaleX and ScaleY properties in Window code behind LayoutTransform is no fire.

So I added handlers to MyControl for ScaleX and ScaleY. I these handlers I manualy do ScaleTransform. This works. So where is problem in TemplateBinding?

With this workaround ScaleTransform works.

    private static void OnScaleXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is MyControl)
        {
            var ctrl = d as MyControl;

            var x = (double) e.NewValue;

            ctrl.LayoutTransform = new ScaleTransform(x, ctrl.ScaleY);

        }
    }

Upvotes: 2

Views: 1650

Answers (1)

Pragmateek
Pragmateek

Reputation: 13364

You have probably hit one of the many limitations of TemplateBinding.

So instead use the equivalent Binding with relative source as the templated parent which is semantically equivalent to TemplateBinding but (slightly) heavier:

<ScaleTransform ScaleX="{Binding ScaleX,RelativeSource={RelativeSource TemplatedParent}}" ScaleY="{Binding ScaleY,RelativeSource={RelativeSource TemplatedParent}}" />

Upvotes: 4

Related Questions