如何检查依赖项对象是否包含依赖项属性?

时间:2009-07-22 09:50:27

标签: c# silverlight

基本上我想要一些简单的反射,其中我有一个任意的DependencyProperty作为参数。如果DependencyProperty由PlaneProjection的/ property定义,我会有一个特殊情况(例如在if语句中)。我已经做了一些简单的GetType(),但是对于像MemberType这样的预期getter没有运气。

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

4 个答案:

答案 0 :(得分:2)

使用扩展方法试用此代码:

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;
    }
}

用法:

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

答案 1 :(得分:1)

这种情况会发生吗?

编辑:仅在WPF中 - 而不是SilverLight。

dp.OwnerType.IsAssignableFrom(typeof(PlaneProjection))

答案 2 :(得分:0)

这应该照顾您在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;
    }
}

答案 3 :(得分:0)

依赖项属性具有默认值,并且在检索它们时总是显示为设置的值。

您可以通过使用帮助程序DependencyPropertyHelper类检索并检查其ValueSource来检查是否已在依赖对象上设置了依赖属性,以及如何设置依赖属性-请考虑以下事项:

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;
}

其中之一可能对您有用;如果可以通过继承设置依赖项属性,并且您对此很在意,则可以检查!IsPropertyDefault。如果您特别在意该属性是否已直接在对象上显式声明,则可以检查IsPropertySetLocally。