WPF で ScaleTransform が凍結されるのはなぜですか?どうすればそれにバインドできますか?

StackOverflow https://stackoverflow.com/questions/2277399

質問

バインドしたい非常に単純なユーザー コントロールがあります。 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 つの質問:

  1. なぜ私のトランスフォームは Frozen 1位ですか?
  2. トランスフォームをクローンするとバインディングが機能しないのはなぜですか?

皆さんありがとう!

アップデート:

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メソッドに渡されるとする密封された/凍結されますされます。

  

しかし、メタデータが消費されると   レジスタへの呼び出しの一環として、   AddOwner、またはOverrideMetadata、   プロパティシステムはそれをシールします   メタデータインスタンスとプロパティ   今不変と考えられています。   一度のDefaultValueを設定しよう   IsSealedこのメタデータに真であります   インスタンスは、例外が発生します。

ScaleTransformはFreezableのあるので、それはこのプロセスの一部として凍結されている

あなたの2番目の質問については、あなたがZoomTransformをクローニングする場合、それは正しくScaleTransformを適用ん提供されているコードに基づきます。あなたが含まれていないことが起こっている何か他のものが存在する必要があります。

これは、ユーザーコントロールのためのXAMLは、X含まれていることを想定している:コードビハインドファイルRoundByRoundControlために結び付けClass属性を

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top