WPF で ScaleTransform が凍結されるのはなぜですか?どうすればそれにバインドできますか?
-
21-09-2019 - |
質問
バインドしたい非常に単純なユーザー コントロールがあります。 ScaleTransform
次のようにコードビハインドの DP にプロパティを追加します。
<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>
そして、背後のコードでこれを実行します。
ZoomTransform.ScaleX = 3;
ZoomTransform.ScaleY = 3;
しかし、次のようなエラーが発生しました。
オブジェクト '...' は読み取り専用状態であるため、プロパティを設定できません。
そこで、次のように変更しました。
var cloned = ZoomTransform.Clone();
cloned.ScaleX = 3;
cloned.ScaleY = 3;
ZoomTransform = cloned;
しかし、今ではそれは実際には何も起こりません...キャンバスにはスケールが適用されません。
しかし
バインディングを外したら ScaleTransform
それを空の XAML 要素として指定するだけです。
<ScaleTransform />
次に、私のコードでこれを行います:
(MyCanvas.RenderTransform as TransformGroup).Children[0] = new ScaleTransform(3, 3);
それは動作します!スケールが適用されました
そこで 2 つの質問:
- なぜ私のトランスフォームは
Frozen
1位ですか? - トランスフォームをクローンするとバインディングが機能しないのはなぜですか?
皆さんありがとう!
アップデート:
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); }
}
解決
あなたはZoomTransformプロパティのデフォルト値として渡すScaleTransformはPropertyMetadataによって凍結されています。 PropertyMetadataは Registerメソッドに渡されるとする密封された/凍結されますされます。
ScaleTransformはFreezableのあるので、それはこのプロセスの一部として凍結されているしかし、メタデータが消費されると レジスタへの呼び出しの一環として、 AddOwner、またはOverrideMetadata、 プロパティシステムはそれをシールします メタデータインスタンスとプロパティ 今不変と考えられています。 一度のDefaultValueを設定しよう IsSealedこのメタデータに真であります インスタンスは、例外が発生します。
あなたの2番目の質問については、あなたがZoomTransformをクローニングする場合、それは正しくScaleTransformを適用ん提供されているコードに基づきます。あなたが含まれていないことが起こっている何か他のものが存在する必要があります。
これは、ユーザーコントロールのためのXAMLは、X含まれていることを想定している:コードビハインドファイルRoundByRoundControlために結び付けClass属性を