Reputation: 356
Essentially I want some simple reflection where I have an arbitrary DependencyProperty as a parameter. I'd have a special case (in an if statement, for example) if DependencyProperty is defined by / property of a PlaneProjection. I've done some simple fandangling of GetType() but no luck with the expected getters like MemberType.
public void SomeFunc(DependencyProperty dp)
{
// if dp is a dependency property of plane projection, do something
// would maybe look like PlaneProjection.hasProperty(dp)
}
Upvotes: 3
Views: 4290
Reputation: 739
Dependency properties have default values and will always appear to be set to something when they're retrieved.
You can check if a dependency property has been set on a dependency object, and if so, how, by retrieving and inspecting its ValueSource with the helper DependencyPropertyHelper class -- consider the following:
public static IsPropertyDefault(this DependencyObject obj, DependencyProperty dp)
{
return DependencyPropertyHelper.GetValueSource(obj, dp).BaseValueSource
== BaseValueSource.Default;
}
public static IsPropertySetLocally(this DependencyObject obj, DependencyProperty dp)
{
return DependencyPropertyHelper.GetValueSource(obj, dp).BaseValueSource
== BaseValueSource.Local;
}
One of these should probably be useful to you; if your dependency property can be set by inheritance and you care about that, you can check !IsPropertyDefault. If you specifically care about whether the property has been explicitly declared directly on the object, you can check IsPropertySetLocally.
Upvotes: 1
Reputation: 14111
Try this code with extension methods:
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;
}
}
Usage:
planeProjection1.HasDependecyProperty(
Helpers.GetStaticMemberName(() => PlaneProjection.CenterOfRotationXProperty));
Upvotes: 2
Reputation: 99869
This should take care of your needs in 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;
}
}
Upvotes: 0
Reputation: 99869
Does this condition catch it?
Edit: Only in WPF - not SilverLight.
dp.OwnerType.IsAssignableFrom(typeof(PlaneProjection))
Upvotes: 1