主要问题在于一些PerformanceCounter属性(例如CategoryName)被标记为
ReadOnly属性。当属性网格看到属性上有ReadOnly属性时,您无法编辑它,因此您无法使用下拉列表查看类别名称列表。
我不知道设计师如何克服这个问题,但这是我的解决方案。我们向正在编辑的PerformanceCounter实例添加自定义
TypeDescriptionProvider,并提供一个自定义类型描述符以删除ReadOnly限制。
以下是如何使用它的方法(使用PropertyGrid类的propertyGrid1实例):
PerformanceCounter counter = new PerformanceCounter()
// use a custom type description provider for this counter
TypeDescriptor.AddProvider(new PerformanceCounterTypeProvider(), counter)
// filter unwanted properties
propertyGrid1.BrowsableAttributes = new AttributeCollection(DesignerSerializationVisibilityAttribute.Visible)
// select it in the property grid
propertyGrid1.SelectedObject = counter
这是使用的实用程序代码:
public class PerformanceCounterTypeProvider : TypeDescriptionProvider
{
private static PropertyDescriptor[] _properties;
static PerformanceCounterTypeProvider()
{
List < PropertyDescriptor> properties = new List<PropertyDescriptor>();
foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(typeof(PerformanceCounter)))
{
PerformanceCounterPropertyDescriptor clone = new PerformanceCounterPropertyDescriptor(pd);
properties.Add(clone);
}
_properties = properties.ToArray();
}
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new PerformanceCounterTypeDescriptor();
}
private class PerformanceCounterTypeDescriptor : CustomTypeDescriptor
{
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return new PropertyDescriptorCollection(PerformanceCounterTypeProvider._properties.ToArray());
}
}
private class PerformanceCounterPropertyDescriptor : PropertyDescriptor
{
private PropertyDescriptor _desc;
public PerformanceCounterPropertyDescriptor(PropertyDescriptor desc)
: base(desc, new List<Attribute>(desc.Attributes.OfType<Attribute>()).ToArray())
{
_desc = desc;
}
public override void SetValue(object component, object value)
{
ComponentType.GetProperty(Name).SetValue(component, value, null);
}
public override bool IsReadOnly
{
get { return false; }
}
public override bool CanResetValue(object component)
{
return _desc.CanResetValue(component);
}
public override Type ComponentType
{
get { return _desc.ComponentType; }
}
public override object GetValue(object component)
{
return _desc.GetValue(component);
}
public override Type PropertyType
{
get { return _desc.PropertyType; }
}
public override void ResetValue(object component)
{
_desc.ResetValue(component);
}
public override bool ShouldSerializeValue(object component)
{
return _desc.ShouldSerializeValue(component);
}
}
}