我昨天在尝试测试我自己的 DependencyProperty 创建类时遇到了类似的问题。我遇到了这个问题,并注意到没有真正的解决方案来取消注册依赖属性。所以我使用Red Gate .NET Reflector进行了一些挖掘,看看我能想出什么。
看着DependencyProperty.Register过载,他们似乎都指向DependencyProperty.RegisterCommon。该方法有两个部分:
首先检查房产是否已经注册
FromNameKey key = new FromNameKey(name, ownerType);
lock (Synchronized)
{
if (PropertyFromName.Contains(key))
{
throw new ArgumentException(SR.Get("PropertyAlreadyRegistered",
new object[] { name, ownerType.Name }));
}
}
二、注册DependencyProperty
DependencyProperty dp =
new DependencyProperty(name, propertyType, ownerType,
defaultMetadata, validateValueCallback);
defaultMetadata.Seal(dp, null);
//...Yada yada...
lock (Synchronized)
{
PropertyFromName[key] = dp;
}
两个部分都DependencyProperty.PropertyFromName以 HashTable 为中心。我还注意到 , DependencyProperty.RegisteredPropertyList,ItemStructList<DependencyProperty>但没有看到它在哪里使用。但是,为了安全起见,我想如果可能的话,我也会尝试从中删除。
所以我结束了下面的代码,它允许我“取消注册”一个依赖属性。
private void RemoveDependency(DependencyProperty prop)
{
var registeredPropertyField = typeof(DependencyProperty).
GetField("RegisteredPropertyList", BindingFlags.NonPublic | BindingFlags.Static);
object list = registeredPropertyField.GetValue(null);
var genericMeth = list.GetType().GetMethod("Remove");
try
{
genericMeth.Invoke(list, new[] { prop });
}
catch (TargetInvocationException)
{
Console.WriteLine("Does not exist in list");
}
var propertyFromNameField = typeof(DependencyProperty).
GetField("PropertyFromName", BindingFlags.NonPublic | BindingFlags.Static);
var propertyFromName = (Hashtable)propertyFromNameField.GetValue(null);
object keyToRemove = null;
foreach (DictionaryEntry item in propertyFromName)
{
if (item.Value == prop)
keyToRemove = item.Key;
}
if (keyToRemove != null)
propertyFromName.Remove(keyToRemove);
}
它工作得很好,我可以运行我的测试而不会出现“AlreadyRegistered”异常。但是,我强烈建议您不要在任何类型的生产代码中使用它。MSFT 选择不使用正式的方式来取消注册依赖项属性可能是有原因的,并且试图违背它只是自找麻烦。