J'ai eu problème similaire juste hier en essayant de tester ma propre DependencyProperty création de classe. Je suis tombé sur cette question, et j'ai remarqué qu'il n'y avait pas vraiment de solution pour supprimer les propriétés de dépendance. J'ai donc creusé en utilisant Red Gate .NET Reflector pour voir ce que je pouvais trouver. En regardant les surcharges DependencyProperty.Register
, ils ont tous semblé pointer vers DependencyProperty.RegisterCommon
. Cette méthode comporte deux parties:
pour vérifier si la propriété 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 }));
}
}
En second lieu, l'enregistrement DependencyProperty
DependencyProperty dp =
new DependencyProperty(name, propertyType, ownerType,
defaultMetadata, validateValueCallback);
defaultMetadata.Seal(dp, null);
//...Yada yada...
lock (Synchronized)
{
PropertyFromName[key] = dp;
}
Les deux centres de pièces autour DependencyProperty.PropertyFromName
, une table de hachage. J'ai également remarqué le DependencyProperty.RegisteredPropertyList
, un ItemStructList<DependencyProperty>
mais je n'ai pas vu où il est utilisé. Cependant, pour des raisons de sécurité, je me suis dit que j'essaierais de m'en débarrasser si possible. Donc je me suis retrouvé avec le code suivant qui m'a permis de "désinscrire" 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é assez bien pour moi d'exécuter mes tests sans obtenir une exception "AlreadyRegistered". Cependant, je vous recommande fortement de ne pas l'utiliser dans un code de production quelconque. Il y a probablement une raison pour laquelle MSFT a choisi de ne pas avoir un moyen formel de désinscrire une propriété de dépendance, et essayer de s'y opposer ne fait que demander des problèmes.
Très bon! Tu as raison de dire que je ne voudrais pas l'utiliser dans le code de production mais un très beau travail de détective! –