I have a pretty simple user control that I want to bind a ScaleTransform
property to a DP in the code behind like so:
<UserControl
x:Name="RoundByRound"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
...
>
<Canvas x:Name="MyCanvas">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding ZoomTransform.ScaleX, ElementName=RoundByRound}"
ScaleY="{Binding ZoomTransform.ScaleY, ElementName=RoundByRound}"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform X="{Binding TranslateTransform.X, ElementName=RoundByRound}"
Y="{Binding TranslateTransform.Y, ElementName=RoundByRound}"/>
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</UserControl>
and then in the code behind I do this:
ZoomTransform.ScaleX = 3;
ZoomTransform.ScaleY = 3;
But I got an error saying:
Cannot set a property on object '...' because it is in a read-only state.
So I changed it to:
var cloned = ZoomTransform.Clone();
cloned.ScaleX = 3;
cloned.ScaleY = 3;
ZoomTransform = cloned;
But now that actually does nothing... no scale gets applied to my canvas.
HOWEVER
If I remove the binding on the ScaleTransform
and just have it as an empty XAML element:
<ScaleTransform />
Then in my code I do this:
(MyCanvas.RenderTransform as TransformGroup).Children[0] = new ScaleTransform(3, 3);
It works! I get the scale applied
So 2 questions:
Frozen
is the first place?Thanks all!
UPDATE:
Here is the definition of the DP:
public static readonly DependencyProperty TranslateTransformProperty = DependencyProperty.Register("TranslateTransform",
typeof(TranslateTransform),
typeof(RoundByRoundControl),
new PropertyMetadata(new TranslateTransform { X = 0, Y = 0 }));
public static readonly DependencyProperty ZoomTransformProperty = DependencyProperty.Register("ZoomTransform",
typeof(ScaleTransform),
typeof(RoundByRoundControl),
new PropertyMetadata(new ScaleTransform { ScaleX = 1, ScaleY = 1 }));
public TranslateTransform TranslateTransform
{
get { return (TranslateTransform)GetValue(TranslateTransformProperty); }
set { SetValue(TranslateTransformProperty, value); }
}
public ScaleTransform ZoomTransform
{
get { return (ScaleTransform)GetValue(ZoomTransformProperty); }
set { SetValue(ZoomTransformProperty, value); }
}
The ScaleTransform that you pass as your default value for your ZoomTransform property is frozen by the PropertyMetadata. Once the PropertyMetadata is passed to the Register method is will be frozen/sealed.
However, once the metadata is consumed as part of a call to Register, AddOwner, or OverrideMetadata, the property system will seal that metadata instance and the properties are now considered immutable. Attempting to set DefaultValue once IsSealed is true on this metadata instance will raise an exception.
Since the ScaleTransform is a Freezable, it is frozen as part of this process.
As for you second question, based on the code you provided it does correctly apply the ScaleTransform when cloning the ZoomTransform. There must be something else going on that you haven't included.
This is assuming that the XAML for your UserControl includes an x:Class attribute which ties to the code-behind file for RoundByRoundControl.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With