本系列文章,是从我的QQ空间转过来的。
上一文中,我们分析了依赖项属性的注册和定义方法,并解释了依赖项属性的注册过程,但是,有一个疑问会困惑着我们,既然依赖项属被声明为静态只读字段,那为什么它的值可以被改变呢?难道你不觉得很奇怪吗?
微软的葫芦里到底卖的什么药呢?我们来看看。
前文中我们提到过,设置依赖项属性的值使用SetValue方法,那好,我们就从SetValue方法入手。
SetValue方法的定义如下:
public void SetValue(DependencyProperty dp, object value)
{
base.VerifyAccess();
PropertyMetadata metadata = this.SetupPropertyChange(dp);
this.SetValueCommon(dp, value, metadata, false, OperationType.Unknown, false);
}
VerifyAccess方法是用于检查可访问性,这个不管它,重点是看SetValueCommon方法,它才是真正设置值的方法,好,继续跟入,看看SetValueCommon方法的定义:
private void SetValueCommon(DependencyProperty dp, object value, PropertyMetadata metadata, bool coerceWithDeferredReference, OperationType operationType, bool isInternal)
{
if (this.IsSealed)
{
throw new InvalidOperationException(SR.Get("SetOnReadOnlyObjectNotAllowed", new object[] { this }));
}
Expression expr = null;
DependencySource[] newSources = null;
EntryIndex entryIndex = this.LookupEntry(dp.GlobalIndex);
if (value == DependencyProperty.UnsetValue)
{
this.ClearValueCommon(entryIndex, dp, metadata);
}
else
{
EffectiveValueEntry entry;
EffectiveValueEntry entry2;
bool flag = false;
bool flag2 = value == ExpressionInAlternativeStore;
if (!flag2)
{
bool flag3 = isInternal ? dp.IsValidValueInternal(value) : dp.IsValidValue(value);
if (!flag3 || dp.IsObjectType)
{
expr = value as Expression;
if (expr != null)
{
if (!expr.Attachable)
{
throw new ArgumentException(SR.Get("SharingNonSharableExpression"));
}
newSources = expr.GetSources();
ValidateSources(this, newSources, expr);
}
else
{
flag = value is DeferredReference;
if (!flag && !flag3)
{
throw new ArgumentException(SR.Get("InvalidPropertyValue", new object[] { value, dp.Name }));
}
}
}
}
if (operationType == Operati