我想通过使用PropertyGrid设置参数来动态创建PerformanceCounter。如果我将PropertyGrid.SelectedObject设置为PerformanceCounter,它不会提供与集成开发环境中相同的选项。

我该怎么做这个戏法呢?这是完全可能的吗?
发布于 2013-06-24 16:52:21
主要问题是一些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)
{
// we can't use _desc.SetValue because the underlying property descriptor checks it's read only
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);
}
}
}发布于 2013-06-23 04:19:19
这会告诉我,默认情况下,propertygrid只会显示那些可以在运行时更改的设置,并且在设计时看到的设置和在运行时看到的设置之间总是存在差异。
https://stackoverflow.com/questions/17156438
复制相似问题