2009-07-22 8 views
2

Essentiellement, je veux une réflexion simple où j'ai un DependencyProperty arbitraire en tant que paramètre. J'aurais un cas particulier (dans une instruction if, par exemple) si DependencyProperty est défini par/property d'un PlaneProjection. J'ai fait un simple fandangling de GetType() mais pas de chance avec les getters attendus comme MemberType.Comment vérifier si un objet de dépendance contient une propriété de dépendance?

public void SomeFunc(DependencyProperty dp) 
{ 
    // if dp is a dependency property of plane projection, do something 
    // would maybe look like PlaneProjection.hasProperty(dp) 
} 

Répondre

1

Essayez ce code avec des méthodes d'extension:

public static class Helpers 
{ 
    public static DependencyProperty FindDependencyProperty(this DependencyObject target, string propName) 
    { 
     FieldInfo fInfo = target.GetType().GetField(propName, BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public); 

     if (fInfo == null) return null; 

     return (DependencyProperty)fInfo.GetValue(null); 
    } 

    public static bool HasDependencyProperty(this DependencyObject target, string propName) 
    { 
     return FindDependencyProperty(target, propName) != null; 
    } 

    public static string GetStaticMemberName<TMemb>(Expression<Func<TMemb>> expression) 
    { 
     var body = expression.Body as MemberExpression; 

     if (body == null) throw new ArgumentException("'expression' should be a member expression"); 

     return body.Member.Name; 
    } 
} 

Utilisation:

planeProjection1.HasDependecyProperty(
    Helpers.GetStaticMemberName(() => PlaneProjection.CenterOfRotationXProperty)); 
+0

Bien que surveillez le BindingFlags.FlattenHierarchy si vous voulez seulement Par exemple, il détecte les DP déclarés sur cette classe, comme cela obtient tous les DP hérités, par exemple FrameworkElement – mattmanser

+0

Eh bien, il ne les "obtient" pas, il ne vérifie que tous les champs hérités. "Largeur" ​​et propriétés similaires héritées –

+0

Eh bien, je ne pouvais pas obtenir cela pour travailler avec mon cas.En particulier, je devrais être capable de dire quelque chose comme: P laneProjection pp = new PlaneProjection(); pp.HasDependencyProperty (PlaneProjection.CenterOfRotationXProperty); // ceci a renvoyé null. Cependant, j'ai dû changer l'appel de HasDependencyProperty à FindDependencyProperty (target, prop.GetType(). Name) pour le compiler correctement. – roblocop

1

Est-ce que cette condition l'attrape?

Modifier: uniquement dans WPF - pas SilverLight.

dp.OwnerType.IsAssignableFrom(typeof(PlaneProjection)) 
+0

Malheureusement, il n » t. Vous pouvez vous attendre à ce que PlaneProjection.CenterOfRotationXProperty.GetType(). IsAssignableFrom (typeof (PlaneProjection) renvoie True, mais cet appel renvoie toujours False.) – roblocop

+0

La propriété 'OwnerType' et la méthode' GetType() 'sont très différentes. est disponible dans SilverLight (c'est dans WPF), alors c'est ce que vous voulez –

+0

Ouais, il semble que la propriété OwnerType n'est pas disponible dans Silverlight.Et cela aurait été utile! – roblocop

0

Cela devrait prendre soin de vos besoins en SilverLight:

private static readonly Dictionary<DependencyProperty, Type> _ownerCache = new Dictionary<DependencyProperty, Type>(); 
// normally you'd use a HashSet<DependencyProperty>, but it's not available in SilverLight 
private static readonly Dictionary<Type, Dictionary<DependencyProperty, bool>> _excludeCache = new Dictionary<Type, Dictionary<DependencyProperty, bool>>(); 

public static bool IsOwnedByTypeOrParent(DependencyProperty dp, Type type) 
{ 
    lock (_ownerCache) 
    { 
     Type owner; 
     if (_ownerCache.TryGetValue(dp, out owner)) 
      return owner.IsAssignableFrom(type); 

     Dictionary<DependencyProperty, bool> exclude; 
     if (_excludeCache.TryGetValue(type, out exclude)) 
     { 
      if (exclude.ContainsKey(dp)) 
       return false; 
     } 

     FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.FlattenHierarchy); 
     foreach (FieldInfo field in fields) 
     { 
      if (typeof(DependencyProperty).IsAssignableFrom(field.FieldType)) 
      { 
       try 
       { 
        object value = field.GetValue(null); 
        if (object.ReferenceEquals(dp, value)) 
        { 
         _ownerCache[dp] = field.DeclaringType; 
         return true; 
        } 
       } 
       catch 
       { 
       } 
      } 
     } 

     if (exclude == null) 
     { 
      exclude = new Dictionary<DependencyProperty, bool>(); 
      _excludeCache[type] = exclude; 
     } 

     exclude.Add(dp, false); 

     /* optional if you want to minimize memory overhead. unnecessary unless 
     * you are using this on enormous numbers of types/DPs 
     */ 
     foreach (var item in _excludeCache) 
     { 
      item.Value.Remove(dp); 
     } 

     return false; 
    } 
} 
Questions connexes