我认为如果您基于 ExpandableObjectConverter 实现自己的 TypeConverter,您可能可以处理这种情况。例如。假设您无法获取 Data2 的数据,所以我假设 Data2 将为 Null。您可以使用自己的转换器在网格中显示属性,但我想知道如何在其前面显示“错误”文本。基本上,对于 Expandable 对象,该类的 ToString() 用于在组中显示文本。
我有一个你可以使用的技巧,可能不是最优雅的解决方案,但我希望它会起作用......你可以做的是在你的类 DisplayedData 添加另一个属性,这样你的类就变成这样了......
public class DisplayedData
{
[TypeConverter(typeof(ExpandableObjectConverter))]
[ReadOnly(true)]
public DataType1 Data1 { get; }
[TypeConverter(typeof(ExpandableObjectConverter))]
[ReadOnly(true)]
[DisplayName("Data2")]
[Browsable(true)]
public DataType2 Data2 { get; } //We have Browsable set to true for this
[DisplayName("Data2")]
[Browsable(false)]
public string Data2Error { get; } //An additional property with Browsable set to false
}
(上面的类没有设置器,我想知道您将如何填充它们,但这可能是部分代码)
现在,当您在此类的对象中填充数据时,您会看到您无法读取 Data2 的值,因此 Data2 为 Null。那你写这个...
if (data.Data2 == null)//data is an object of DisplayedData class that we are showing in PropertyGrid
{
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(data.GetType())["Data2"];
BrowsableAttribute attribute = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
FieldInfo fieldToChange = attribute.GetType().GetField("Browsable",
BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Public |
BindingFlags.Instance);
fieldToChange.SetValue(attribute, false);
data.Data2Error = "Error";
descriptor = TypeDescriptor.GetProperties(data.GetType())["Data2Error"];
attribute = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
fieldToChange = attribute.GetType().GetField("Browsable",
BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Public |
BindingFlags.Instance);
fieldToChange.SetValue(attribute, true);
}
propertyGrid1.SelectedObject = data; //Reassign object to PropertyGrid
基本上在运行时我们试图隐藏属性 Data2 并显示属性 Data2Error,这两个属性具有相同的显示名称,因此在属性网格中显示相同的名称。为此,我们使用反射并获取属性“Browsable”并设置其属性。