WPF why is my ScaleTransform Frozen and how can I get attached to it?

I have a pretty simple user control that I want to bind to the ScaleTransform property to DP in code that looks like this:

 <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 message:

It is not possible to set a property on the 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 this actually does nothing ... no scale applies to my canvas.

HOWEVER

If I remove the binding on a ScaleTransform and just set 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 applied scale

So, 2 questions:

  • Why is my Frozen conversion first place?
  • Why doesn't my binding work when I clone a transform?

Thanks everyone!

UPDATE:

Here is the definition of 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); } } 
+4
source share
1 answer

The ScaleTransform that you pass as the default for your ZoomTransform property is measured by PropertyMetadata. When the PropertyMetadata passed to the Register method is frozen / sealed.

However, when metadata is consumed as part of a registration application, AddOwner or OverrideMetadata, the property system will seal this instance of metadata and the properties are now considered unchanged. Attempting to set DefaultValue once IsSealed true in this instance metadata will throw an exception.

Since ScaleTransform is Freezable, it is frozen as part of this process.

Regarding the second question, based on the code you provided, it correctly applies ScaleTransform when cloning ZoomTransform. There must be something else that you have not included.

This assumes that the XAML for your UserControl includes the x: Class attribute, which is associated with the code file for RoundByRoundControl.

0
source

Source: https://habr.com/ru/post/1301515/


All Articles