WPF控件的附加属性
我仍在致力于WPF应用程序的自动化测试。我需要通过名称访问属性来实现这一点 目前我想知道WPF控件的附加属性。我试图遍历Button对象的所有属性,认为我也可以找到附加属性。但是我找不到他们 因此,我使用Snoop进行了检查,它列出了许多属性,如“KeyboardNavigation.AcceptsReturn”和“ToolTipManager.ToolTipKey”,这些属性应该被附加到属性中 我使用以下代码创建按钮“对象”的(附加)属性的名称列表:WPF控件的附加属性,wpf,dependency-properties,attached-properties,system.reflection,snoop,Wpf,Dependency Properties,Attached Properties,System.reflection,Snoop,我仍在致力于WPF应用程序的自动化测试。我需要通过名称访问属性来实现这一点 目前我想知道WPF控件的附加属性。我试图遍历Button对象的所有属性,认为我也可以找到附加属性。但是我找不到他们 因此,我使用Snoop进行了检查,它列出了许多属性,如“KeyboardNavigation.AcceptsReturn”和“ToolTipManager.ToolTipKey”,这些属性应该被附加到属性中 我使用以下代码创建按钮“对象”的(附加)属性的名称列表: Type^Type=object->Get
Type^Type=object->GetType();
while(类型)
{
数组^fi=type->GetFields(BindingFlags::DeclaredOnly | BindingFlags::Static | BindingFlags::Public);
对于(int i=0;i长度;i++)
{
dependencProperty ^dp=动态_cast(fi[i]>GetValue(object));
如果(dp)
{
DependencyPropertyDescriptor ^dpd=DependencyPropertyDescriptor::FromProperty(dp,类型);
如果(dpd->IsAttached)
{
属性名称->添加(fi[i]->名称);
}
}
}
类型=类型->基本类型;
}
但是,IsAttached始终为false,并且生成的lsit为空。如果没有“IsAttached”检查,我会得到一个很好的属性列表,但是没有任何预期的附加属性
不以这种方式列出附加属性吗
我想我现在更好地理解了附加属性的用法。然而,我不能真正解决我的问题。 提到的本地枚举数仅获取在本地对象上设置的属性,而不是对象的所有可用属性 请让我解释一下我的意图:我只以附属财产的名称开始。。。我首先需要检查所附的属性是否存在(这可能意味着它是否已注册,对吗?)。然后我想获取附加属性的值,该值可能是我的对象的本地设置值(如果设置了),也可能是默认值 目前我不知道如何检查是否存在附加属性。是否有提供所有可用附加属性列表的功能?我可以使用它来验证给定的属性名称,并获取相应的属性对象 附加属性与中的正常依赖项属性不同 有几种方法。最值得注意的是,它们没有包装在CLR中 属性(即标准.NET属性) 请查看更多详细信息
您可能想尝试使用GetLocalValueEnumerator迭代您的属性抱歉,工作一直让我很忙。您可以这样做: 假设xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button x:Name="btn" Grid.Column="1"/>
</Grid>
注意:这是使用私有成员和类,MS很可能在将来的版本中更改这些成员和类。非常好,谢谢!这段代码符合我的要求,我只需要一些修改。令人遗憾的是,它需要一个内部的实现细节,而且没有官方的API来实现它。我仍然想知道(但并不阻止我使用代码)snoop到底做了什么。。。通过您的代码,我可以获得更多的附加(和非附加)依赖属性列表。在某种程度上,snoop似乎可以过滤与所选对象相关的附加属性。首先,我认为只有那些由snoop列出的、在所选对象中具有本地设置值的附加依赖属性(ADP)。但事实并非如此。实际上,Snoop列出的大多数ADP在所选对象上没有本地值。因此,必须有另一种解释。你知道有没有办法检查ADP是否与某个对象或其类型相关?
<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));