J'ai eu un problème similaire hier en essayant de tester ma propre classe de création de DependencyProperty. Je suis tombé sur cette question, et j'ai remarqué qu'il n'y avait pas de solution réelle pour désenregistrer les propriétés de dépendance. J'ai donc fait quelques recherches en utilisant Red Gate .NET Reflector pour voir ce que je pouvais trouver.
En regardant la DependencyProperty.Register
surcharges, ils semblaient tous indiquer que les DependencyProperty.RegisterCommon
. Cette méthode comporte deux parties :
Vérifier d'abord si le bien est déjà enregistré
FromNameKey key = new FromNameKey(name, ownerType);
lock (Synchronized)
{
if (PropertyFromName.Contains(key))
{
throw new ArgumentException(SR.Get("PropertyAlreadyRegistered",
new object[] { name, ownerType.Name }));
}
}
Deuxièmement, enregistrement de la propriété de dépendance
DependencyProperty dp =
new DependencyProperty(name, propertyType, ownerType,
defaultMetadata, validateValueCallback);
defaultMetadata.Seal(dp, null);
//...Yada yada...
lock (Synchronized)
{
PropertyFromName[key] = dp;
}
Les deux pièces s'articulent autour de DependencyProperty.PropertyFromName
, une table de hachage. J'ai également remarqué que le DependencyProperty.RegisteredPropertyList
, un ItemStructList<DependencyProperty>
mais je n'ai pas vu où elle était utilisée. Toutefois, pour des raisons de sécurité, je me suis dit que je devais essayer de m'en débarrasser si possible.
J'ai donc obtenu le code suivant qui me permet de "désenregistrer" une propriété de dépendance.
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);
}
Cela a fonctionné suffisamment bien pour que je puisse exécuter mes tests sans obtenir une exception "AlreadyRegistered". Cependant, je vous recommande fortement de ne l'utilisez pas dans un code de production. Il y a probablement une raison pour laquelle MSFT a choisi de ne pas avoir de moyen formel de désenregistrer une propriété de dépendance, et tenter d'aller à l'encontre de ce choix est une source d'ennuis.