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
是第一名吗? - 当我克隆转换时,为什么我的绑定不起作用?
谢谢大家!
更新:
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 方法 将被冷冻/密封。
但是,一旦将元数据作为注册,附加器或OverrideMetadata的呼叫的一部分,则该属性系统将密封该元数据实例,并且该属性现在被视为不可分流。在此元数据实例上进行否定后,试图设置DefaultValue将会引起例外。
由于 ScaleTransform 是 Freezable,因此它在此过程中被冻结。
至于你的第二个问题,根据你提供的代码,它在克隆 ZoomTransform 时正确应用了 ScaleTransform。一定还有其他事情发生,你没有包括在内。
假设 UserControl 的 XAML 包含 x:Class 属性,该属性与 RoundByRoundControl 的代码隐藏文件相关联。
不隶属于 StackOverflow