Just a quick post. If you're obsessed with beautiful and clean XAML code like I am, a real thorn in your side is probably seeing this all over the place in a project with lots of animations:
<Rectangle Width="100" Height="100" Fill="LightGreen" RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="2.5" ScaleY="1" />
<SkewTransform AngleX="-60" />
<RotateTransform Angle="145" />
<TranslateTransform />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
That's because Blend crashes and burns if you don't have the whole damn TransformGroup
in there even if all you need is a TranslateTransform
to animate over. Wouldn't it be nice to be able to work on your animations in Blend while having something like this instead:
<Rectangle Width="100" Height="100" Fill="LightGreen"
RenderTransform="{data:CompositeTransform ScaleX=2.5, ScaleY=1, SkewX=-60, Rotation=145}"
RenderTransformOrigin="0.5,0.5" />
Well you're in luck :) Unlike some other approaches, the following code still works with Blend because it returns a TransformGroup
with the expected transforms in the expected order. Here you go:
public class CompositeTransformExtension : MarkupExtension
{
private ScaleTransform _scale = new ScaleTransform();
private SkewTransform _skew = new SkewTransform();
private RotateTransform _rotate = new RotateTransform();
private TranslateTransform _translate = new TranslateTransform();
public CompositeTransformExtension()
{
}
public double CenterX
{
get { return _scale.CenterX; }
set
{
_scale.CenterX = value;
_skew.CenterX = value;
_rotate.CenterX = value;
}
}
public double CenterY
{
get { return _scale.CenterY; }
set
{
_scale.CenterY = value;
_skew.CenterY = value;
_rotate.CenterY = value;
}
}
public double ScaleX
{
get { return _scale.ScaleX; }
set { _scale.ScaleX = value; }
}
public double ScaleY
{
get { return _scale.ScaleY; }
set { _scale.ScaleY = value; }
}
public double SkewX
{
get { return _skew.AngleX; }
set { _skew.AngleX = value; }
}
public double SkewY
{
get { return _skew.AngleY; }
set { _skew.AngleY = value; }
}
public double Rotation
{
get { return _rotate.Angle; }
set { _rotate.Angle = value; }
}
public double TranslateX
{
get { return _translate.X; }
set { _translate.X = value; }
}
public double TranslateY
{
get { return _translate.Y; }
set { _translate.Y = value; }
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var group = new TransformGroup();
group.Children.Add(_scale);
group.Children.Add(_skew);
group.Children.Add(_rotate);
group.Children.Add(_translate);
return group;
}
}