WPF pourquoi mon ScaleTransform Congelés et comment puis-je lier à elle?
-
21-09-2019 - |
Question
J'ai un contrôle utilisateur assez simple que je veux lier une propriété ScaleTransform
à un DP dans le code sous-jacent comme ceci:
<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>
puis dans le code derrière moi ceci:
ZoomTransform.ScaleX = 3;
ZoomTransform.ScaleY = 3;
Mais je suis une erreur en disant:
Impossible de définir une propriété sur l'objet « ... » parce qu'il est dans un état de lecture seule.
Alors je l'ai changé:
var cloned = ZoomTransform.Clone();
cloned.ScaleX = 3;
cloned.ScaleY = 3;
ZoomTransform = cloned;
Mais maintenant, qui ne fait rien ... pas d'échelle soit appliquée à ma toile.
CEPENDANT
Si je supprime la liaison sur la ScaleTransform
et juste comme un élément XAML vide:
<ScaleTransform />
Alors dans mon code que je fais ceci:
(MyCanvas.RenderTransform as TransformGroup).Children[0] = new ScaleTransform(3, 3);
Il fonctionne! Je me l'échelle appliqué
2 questions:
- Pourquoi mon Transform
Frozen
est le premier lieu? - Pourquoi ne marche pas mon travail de liaison quand je clone la transformation?
Merci à tous!
Mise à jour:
Voici la définition du 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); }
}
La solution
Le ScaleTransform que vous passez comme valeur par défaut de votre propriété ZoomTransform est gelé par le PropertyMetadata. Une fois que le PropertyMetadata est passé à la méthode Register est sera gelé / scellé.
Cependant, une fois les métadonnées est consommé dans le cadre d'un appel à inscrire, Addowner ou OverrideMetadata, la système de propriété scellera que par exemple les métadonnées et les propriétés sont maintenant considérés comme immuables. Tentative de définition DefaultValue une fois IsSealed est vrai sur ces métadonnées par exemple déclenche une exception.
Depuis la ScaleTransform est un Freezable, il est gelé dans le cadre de ce processus.
Quant à vous deuxième question, sur la base du code à condition qu'il ne s'applique correctement le ScaleTransform lors du clonage du ZoomTransform. Il doit y avoir quelque chose d'autre à faire que vous ne l'avez pas inclus.
Cela suppose que le XAML pour votre UserControl comprend un x:. Attribut de classe qui lie au fichier code-behind pour RoundByRoundControl