WPF, warum ist meine Scaletransform gefriert und wie kann ich daran binden?
-
21-09-2019 - |
Frage
Ich habe eine ziemlich einfache Benutzersteuerung, dass ich hinter wie so eine ScaleTransform
Immobilie an einen DP im Code binden möge:
<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>
und dann in dem Code hinter ich dies tun:
ZoomTransform.ScaleX = 3;
ZoomTransform.ScaleY = 3;
Aber ich habe einen Fehler zu sagen:
Kann nicht eine Eigenschaft auf dem Objekt gesetzt ‚...‘, weil es in einem Nur-Lese-Zustand ist.
So habe ich es zu:
var cloned = ZoomTransform.Clone();
cloned.ScaleX = 3;
cloned.ScaleY = 3;
ZoomTransform = cloned;
Aber jetzt, wo eigentlich nichts tut ... kein Maßstab auf meine Leinwand aufgetragen wird.
JEDOCH
Wenn ich die Bindung an dem ScaleTransform
entfernen und habe es nur als leeres XAML-Element:
<ScaleTransform />
Dann in meinem Code ich dies tun:
(MyCanvas.RenderTransform as TransformGroup).Children[0] = new ScaleTransform(3, 3);
Es funktioniert! Ich erhalte die Skala angewendet
So 2 Fragen:
- Warum ist mein Trans
Frozen
ist der erste Ort? - Warum meine Bindung nicht funktioniert, wenn ich klonen die Transformation?
Danke allen!
UPDATE:
Hier ist die Definition des 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); }
}
Lösung
Die Scaletransform, dass Sie als Standardwert für Ihre ZoomTransform Eigenschaft übergeben wird durch die PropertyMetadata eingefroren. Sobald die PropertyMetadata auf die Register-Methode weitergegeben ist, wird eingefroren / versiegelt werden.
Sobald jedoch die Metadaten verbraucht wird als Teil eines Anrufs zu registrieren, AddOwner oder OverrideMetadata, die Eigenschaft System abdichten, dass Metadaten-Instanz und die Eigenschaften werden nun unveränderlich angesehen. Der Versuch, zu setzen Default einmal IsSealed trifft auf diese Metadaten Beispiel wird eine Ausnahme ausgelöst.
Da die Scaletransform ein Freezable ist, wird es als Teil dieses Prozesses eingefroren.
Was Sie betrifft zweite Frage, basierend auf dem Code versehen Sie es richtig, die Scaletransform gilt, wenn die ZoomTransform klonen. Es muss etwas anderes sein würde, dass Sie nicht aufgenommen haben.
Dies wird unter der Annahme, dass die XAML für Ihren Usercontrol enthält ein x. Class-Attribut, die Bindung an die Code-Behind-Datei für RoundByRoundControl