1

Я все еще работаю над автоматическим тестированием приложений 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» я получаю хороший список свойств, но без каких-либо ожидаемых вложенных свойств.

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


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

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

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

ответ

0

К сожалению, работа держит меня заняты. Вы можете сделать это:

Допуская 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 может также изменить в некоторой будущей версии.

+0

Очень приятно, спасибо! Этот код делает то, что я хочу, мне нужно всего лишь несколько модификаций. Какой позор, что ему нужны детали внутренней реализации и что для этого нет официального API. – Silicomancer

+0

Что еще заставляет меня задаться вопросом (но не мешает мне использовать код) то, что точно snoop делает ... С вашим кодом я получаю гораздо больший список прикрепленных (и не связанных) свойств зависимостей. В некотором смысле snoop, кажется, фильтрует прикрепленные свойства относительно выбранного объекта. – Silicomancer

+0

Сначала я думал, что только привязанные свойства зависимостей (ADP), которые перечислены Snoop, имеют локально установленные значения в выбранном объекте. Но это не факт. Фактически большинство ADP, перечисленных Snoop, не имеют локального значения для выбранного объекта. Поэтому должно быть другое объяснение. Знаете ли вы, есть ли способ проверки ADP для какой-либо «релевантности» в отношении объекта или его типа? – Silicomancer

2

Прилагаемые свойства отличаются от обычных зависимых свойств в несколькими способами. Наиболее заметным является то, что они не завернуты в свойства 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