Список вложенных свойств в Silverlight - PullRequest
2 голосов
/ 30 ноября 2009

Кто-нибудь знает, как перечислить прикрепленные свойства, которые были установлены для UIElement в Silveright 3? Множество решений WPF как обычно!

Приветствия

Ответы [ 2 ]

1 голос
/ 01 декабря 2009

Довольно ужасная хрупкая реализация, которую я решил использовать, заключалась в следующем: сканирование загруженных сборок в поисках свойств зависимостей. Если было свойство зависимости с соответствующим публичным статическим методом Getxxx / Setxxx, тогда это было присоединенное свойство. Очевидно, что у него много дыр, но пока он мне поможет.

Причина, по которой я хочу получить список прикрепленных свойств, заключается в том, что я могу посмотреть, какие вложенные свойства установлены в объекте @ runtime, и изменить их только для отладки.

Код ниже:

public static List<DependencyProperty> GetAttachedProperties(Object element)
    {
        List<DependencyProperty> attachedProperties = new List<DependencyProperty>();

        foreach (AssemblyPart ap in Deployment.Current.Parts)
        {
            StreamResourceInfo sri = Application.GetResourceStream(new Uri(ap.Source, UriKind.Relative));
            Assembly a = new AssemblyPart().Load(sri.Stream);
            GetAttachedProperties(a, attachedProperties);
        }


        return attachedProperties;

    }

    private static void GetAttachedProperties(Assembly a, List<DependencyProperty> attachedProperties)
    {
        foreach (var type in a.GetTypes())
        {
            Debug.WriteLine(type.FullName);
            var dependencyProperties = type.GetFields(BindingFlags.Static | BindingFlags.Public).Where(
                f => typeof (DependencyProperty).IsAssignableFrom(f.FieldType)).Select(f => f);
            foreach (var dp in dependencyProperties)
            {
                FieldInfo info = dp;
                var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
                Debug.WriteLine("{0} suitable dp methods found", methods.Count());
                var fields = methods.Where(
                    m => (IsAttachedGetter(m, info) || IsAttachedSetter(m, info))).Select(
                    m => info).ToArray();
                foreach(var field in fields)
                {
                    try
                    {
                        Debug.WriteLine("Adding dependency property {0} from type {1}", dp.Name, type.FullName);
                        attachedProperties.Add((DependencyProperty)field.GetValue(null));
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine("Error getting dependency property {0} from type {1}, exception: {2}",
                            dp.Name, type.FullName, e);
                    }
                }
            }
        }
    }

    private static bool IsAttachedSetter(MethodInfo methodInfo, FieldInfo info)
    {
        string setName = string.Format("Set{0}", info.Name.Replace("Property", string.Empty));
        if(methodInfo.Name == setName)
        {
            var methodParams = methodInfo.GetParameters();
            return methodParams.Count() == 2
                   && typeof (DependencyObject).IsAssignableFrom(methodParams[0].ParameterType);
        }
        return false;
    }

    private static bool IsAttachedGetter(MethodInfo methodInfo, FieldInfo info)
    {
        string getName = string.Format("Get{0}", info.Name.Replace("Property", string.Empty));
        if(methodInfo.Name == getName)
        {
            var methodParams = methodInfo.GetParameters();
            return methodParams.Count() == 1 &&
                   methodParams[0].ParameterType.IsAssignableFrom(typeof (DependencyObject));
        }
        return false;
    }
1 голос
/ 01 декабря 2009

Краткий ответ: это невозможно сделать.

Silverlight DependencyObject не имеет GetLocalValueEnumerator, который позволяет это для WPF. Фактически единственный метод, который предлагает проблеск - это ReadLocalValue.

Следовательно, если вы действительно интересуетесь только определенным подмножеством свойств, вы можете попробовать каждое из них по очереди через ReadLocalValue. Хотя крайне неудовлетворительно для общего требования.

Мне любопытно, что могло бы привести к такому требованию?

...