5

我有一个非常简单的用户控件,我想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. 为什么我的TransformFrozen是第一位的?
  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); }
        }
4

1 回答 1

2

您作为 ZoomTransform 属性的默认值传递的 ScaleTransform 被 PropertyMetadata 冻结。一旦 PropertyMetadata 被传递给 Register 方法,就会被冻结/密封。

但是,一旦元数据作为对 Register、AddOwner 或 OverrideMetadata 的调用的一部分被使用,属性系统将密封该元数据实例,并且这些属性现在被认为是不可变的。一旦 IsSealed 在此元数据实例上为真,尝试设置 DefaultValue 将引发异常。

由于 ScaleTransform 是 Freezable,因此在此过程中将其冻结。

至于第二个问题,根据您提供的代码,它在克隆 ZoomTransform 时确实正确应用了 ScaleTransform。一定还有其他你没有包括在内的事情发生。

这是假设您的 UserControl 的 XAML 包含一个 x:Class 属性,该属性与 RoundByRoundControl 的代码隐藏文件相关联。

于 2011-05-19T00:13:34.500 回答