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);
}
}
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 toTemplateBinding
but (slightly) heavier: