注意:这个问题也被标记为C#,因为它是一般问题而且是 回答描述在C#中使用它对我来说完全没问题。
我最近在.Net Framework中探索过PropertyGrid。我检查了这个属性(BrowsableAttributes),我不知道它的使用。
起初我认为这可以循环遍历BrowsableAttribute
中的每个SelectedObject
,然后您就能找回原来的属性,这本来是有用的。
但不,显然所有这些属性都会为您提供AttributeCollection
仅包含BrowsableAttribute
,所有设置为True
...
有人可以告诉我这种方法有什么意义吗?我甚至不明白它在.NET中是如何有用的......
Dim attributes = MyPropertyGrid.BrowsableAttributes
For Each A As Attribute In attributes
Dim Browsable As BrowsableAttribute = CType(A, BrowsableAttribute)
'Then how can I use this ? it's only property is Browsable (True/False)
Next
我原本试图解决一个问题,我不知道在属性网格中选择了哪个对象,但我想收集对象的数据。
我不知道对象的类型是什么,因为它来自动态加载的DLL。我只知道它是另一个派生类,我知道。但是我很有兴趣备份从Property Grid获得的Object属性,以便以后能够保存和加载它们。
由于属性网格已经包含了所有这些值,我认为这种属性可能是编写更多代码的重点。我不想在Property Grid已经使用反射来检查代码。
答案 0 :(得分:4)
PropertyGrid使用类似to this answer的方法迭代对象的所有属性。在它执行此操作时,它会检查与该属性关联的所有属性,并检查它是否可以找到与AttributeCollection的匹配(示例代码,如何执行此操作is here)。如果它能找到它,它将显示在属性网格中,否则不显示。
目的是,如果您需要黑名单支持,可以隐藏公共属性以显示在属性网格中,或者使用[Browsable(false)]
标记它。如果您喜欢白名单方法,则可以定义自己的属性,将其应用于所有需要的属性,并将BrowsableAttribute
设置为仅包含您自己的属性的集合。
答案 1 :(得分:3)
BrowsableAttributes
财产的工作已在文件中清楚地描述:
只有属性与指定值匹配的属性才有 显示在PropertyGrid中。默认值为AttributeCollection 仅包含BrowsableAttribute.Yes。
但它是如何运作的?
.NET Framework有两种机制来查找类型的元数据:
通过类型的反射返回的元数据是不可扩展的,并且在编译类型后无法修改,而TypeDescriptor
返回的元数据可以使用IExtenderProvider
,ITypeDescriptorFilterService
进行更改或ICustomTypeDescriptor
。
例如,这是类型描述机制,它使设计人员能够添加一些设计时属性,这些属性不是Modifier
,Locked
或GenerateMember
等对象的实际属性。
PropertyGrid
使用TypeDescriptor
机制以这种方式获取属性:
var properties = TypeDescriptor.GetProperties(component, attributes);
它依赖于TypeDescriptor.GetProperties
方法,您可以在文档的备注部分找到过滤规则。
上述方法中的component
为SelectedObject
PropertyGrid
且attributes
为BrowsableAttributes
属性,并且仅在文档中描述属性与属性匹配的属性显示在PropertyGrid
中。由于默认情况下基于惯例,我们预期[Brawsable(false)]
中的PropertyGrid
属性不会显示在Browsable
中,因此该属性包含Yes
属性值class ThreadSessionRequest(object):
def __init__(self, request, *args, **kwargs):
self.s = Session()
def __del__(self):
if self.s:
self.remove_session()
def remove_session(self):
if self.s:
try:
self.safe_commit()
finally:
Session.remove()
del self.s
self.s = None
def safe_commit(self):
if self.s:
try:
self.s.commit()
except:
self.s.rollback()
raise
。