Прикрепленные свойства элементов управления WPF

Я все еще работаю над автоматизированным тестированием приложений WPF. Мне нужно получить доступ к свойствам по имени, чтобы добиться этого.

В настоящее время я задаюсь вопросом о вложенных свойствах элементов управления WPF. Я пытался перебрать все свойства объекта Button, думая, что я тоже могу найти вложенные свойства. Но я не мог их найти.

Поэтому я проверил с помощью Snoop, и он перечисляет множество свойств, таких как "KeyboardNavigation.AcceptsReturn" и "ToolTipManager.ToolTipKey", к которым должны быть прикреплены свойства AFAIK.

Я использовал следующий код для создания списка имен (прикрепленных) свойств кнопки "объект":

   Type^ type = object->GetType();
   while (type)
   {
      array<FieldInfo^>^ fi = type->GetFields(BindingFlags::DeclaredOnly | BindingFlags::Static | BindingFlags::Public);
      for (int i=0; i<fi->Length; i++)
      {
         DependencyProperty^ dp = dynamic_cast<DependencyProperty^>(fi[i]->GetValue(object));
         if (dp)
         {
            DependencyPropertyDescriptor^ dpd = DependencyPropertyDescriptor::FromProperty(dp, type);
            if (dpd->IsAttached)
            {
               propertyNames->Add(fi[i]->Name);
            }
         }
      }

      type = type->BaseType;
   }

Однако IsAttached всегда ложно, а полученный lsit пуст. Без проверки "IsAttached" я получаю хороший список свойств, но без каких-либо ожидаемых вложенных свойств.

Не отражает список прикрепленных свойств таким образом?


Я думаю, что теперь я лучше понимаю использование прикрепленных свойств. Однако я не мог решить мою проблему. Упомянутый локальный перечислитель получает только те свойства, которые установлены для объекта локально, а не все свойства, доступные для объекта.

Пожалуйста, позвольте мне объяснить, что я намереваюсь: я начинаю только с имени присоединенного свойства... Сначала я должен проверить, существует ли это присоединенное свойство (что, вероятно, означает, если оно зарегистрировано, верно?). Затем я хочу получить значение присоединенного свойства, которое может быть локально установленным значением для моего объекта (если оно было установлено) или значением по умолчанию в противном случае.

В настоящее время я не знаю, как проверить, существует ли прикрепленное свойство. Может быть, есть какая-то функция, предоставляющая список всех доступных вложенных свойств? Я мог бы использовать его для проверки заданного имени свойства и для извлечения соответствующего объекта свойства.

2 ответа

Решение

Извините, работа не давала мне покоя. Вы могли бы сделать это:

Предполагая xaml:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <Button x:Name="btn" Grid.Column="1"/>

</Grid>

Следующий код должен дать вам несколько вариантов:

    //do this if you can:
    btn.GetValue(Grid.ColumnProperty);

    //Otherwise,
    //gets all the dependency properties in the app domain
    Type depType = typeof(DependencyProperty) ;
    FieldInfo info = depType.GetField("PropertyFromName", BindingFlags.NonPublic | BindingFlags.Static);
    Hashtable AllDependencyProperties = info.GetValue(null) as Hashtable;

    //Index the hashtable of all dependency properties using a FromNameKey type            
    Type FromNameKeyType = depType.Assembly.GetType("System.Windows.DependencyProperty+FromNameKey");            
    ConstructorInfo ctor = FromNameKeyType.GetConstructor(new Type[] { typeof(String), typeof(Type) });
    var NameKey = ctor.Invoke(new object[] { "Column", typeof(Grid) });

    //index the hashtable to get the Dependency property
    DependencyProperty dp = AllDependencyProperties[NameKey] as DependencyProperty;

    //use the dp to get the value
    btn.GetValue(dp);


    //Or, without indexing a list of all dependency properties
    //get a dependency property by name
    System.Reflection.MethodInfo FromNameMethod = depType.GetMethod("FromName",System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic );
    var ret = FromNameMethod.Invoke(null, new object[] { "Column", typeof(Grid) });

    //use it to get a value from an object
    btn.GetValue((ret as DependencyProperty));

Предостережение: здесь используются закрытые члены и классы, которые MS вполне может изменить в будущей версии.

Прикрепленные свойства отличаются от обычных свойств зависимостей несколькими способами. Наиболее заметным является то, что они не заключены в свойства CLR (то есть стандартные свойства.NET).

Взгляните на http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-attached-properties-in-wpf/ для получения более подробной информации.

Возможно, вы захотите попробовать использовать GetLocalValueEnumerator для перебора ваших свойств http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.getlocalvalueenumerator.aspx

Другие вопросы по тегам