据我所知,这是因为freezable设计与DependencyObject基础设施紧密耦合,其行为与资源系统类似,原因相同。
Loaded
实际实例值不再冻结,因为它们已耦合到此特定实例。
下面是Freezable.cs中的一个片段。DependencyProperty在freezable上调用DependencyObject.Seal()时,会调用ISealable.Seal()的重写,从而导致实例冻结:
void ISealable.Seal()
{
Freeze();
}
private static void ValidateDefaultValueCommon(
object defaultValue,
Type propertyType,
string propertyName,
ValidateValueCallback validateValueCallback,
bool checkThreadAffinity)
{
if (!IsValidType(defaultValue, propertyType))
{
throw new ArgumentException(SR.Get(SRID.DefaultValuePropertyTypeMismatch, propertyName));
}
if (defaultValue is Expression )
{
throw new ArgumentException(SR.Get(SRID.DefaultValueMayNotBeExpression));
}
if (checkThreadAffinity)
{
DispatcherObject dispatcherObject = defaultValue as DispatcherObject;
if (dispatcherObject != null && dispatcherObject.Dispatcher != null)
{
ISealable valueAsISealable = dispatcherObject as ISealable;
if (valueAsISealable != null && valueAsISealable.CanSeal)
{
Invariant.Assert (!valueAsISealable.IsSealed,
"A Sealed ISealable must not have dispatcher affinity");
valueAsISealable.Seal();
Invariant.Assert(dispatcherObject.Dispatcher == null,
"ISealable.Seal() failed after ISealable.CanSeal returned true");
}
else
{
throw new ArgumentException(SR.Get(SRID.DefaultValueMustBeFreeThreaded, propertyName));
}
}
}
在上面的代码中,您可以找到说明:
我们不能接受它作为默认值。如果它实现了ISealable
允许从DispatcherObject派生-由用户决定
摘要:Style、FrameworkTemplate、Brush或Freezable(例如Brush)等类型都实现了ISealable,而Freezable提供的实现调用了Freeze()。设定
默认值
DependencyProperty的调用会导致DependencyProperty调用ISealable.Seal()。
因此,当将克隆数据(将IsFrozed设置为false)指定给PropertyMetadata作为默认值时,将再次冻结。由于您正在对该默认值进行操作,因此在修改它时将出现异常。