问题
I'm trying to change the Browsable attribute of a variable in one of my classes at runtime. The class containing the attribute looks like this:
public class DisplayWallType : WallType
{
[TypeConverter(typeof(SheathingOptionsConverter))]
[Browsable(false)]
public override Sheathing SheathingType { get; set; }
public DisplayWallType(string passedName, string passedType, bool passedMirrorable, Distance passedHeight, string passedStudPattern, Distance passedStudSpacing, VaporBarrier passedBarrier)
: base(passedName, passedType, passedMirrorable, passedHeight, passedStudPattern, passedStudSpacing, passedBarrier)
{
}
/// <summary>
/// Empty constructor for XML serialization
/// </summary>
public DisplayWallType()
{
}
}
I initially set it to false for SheathingType because I don't want that attribute to show up in the first form of my application. However, I do want it visible in my second form so I have this method to change it
private void _makeSheathingVisible(DisplayWallType wallTypeToMakeSheathingVisible)
{
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(wallTypeToMakeSheathingVisible.GetType())["SheathingType"];
BrowsableAttribute attrib = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
FieldInfo isBrow = attrib.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
isBrow.SetValue(attrib, true);
}
That method above takes a DisplayWallType object and ensures that Browsable is set to true. My second form is a treeview combined with a property grid. The treeview is populated with instances of DisplayWallType and when one is selected, it is passed into that method so that SheathingType shows up in the PropertiesGrid with the rest of the properties from the parent class.
However, SheathingType still does not show up as a property so something is wrong with my approach but I have no idea what
回答1:
You cannot get Browsable
attribute for one exact property except you have its TypeDescriptor
explicit declaration. In your case GetField("browsable")
will return FieldInfo
for all properties and will switch them to visible true. The same thing will appear if you have some properties and set one browsable to false - it will hide all properties.
Provide a custom TypeDescriptor for needed attributes or use some solutions like https://www.codeproject.com/articles/7852/propertygrid-utilities.
回答2:
I know this issue is from some time ago, but I fixed the same issue today by calling propertiesGrid.Refresh() after changing the Browsable attribute. Maybe it helps someone in the future.
回答3:
RefreshPropertiesAttribute Class Indicates that the property grid should refresh when the associated property value changes.
[TypeConverter(typeof(SheathingOptionsConverter))]
[Browsable(false)] // changes at runtime
public override Sheathing SheathingType { get; set; }
private bool updateWhenChanged;
[RefreshProperties(RefreshProperties.All)]
public bool UpdateWhenChanged
{
get => updateWhenChanged;
set
{
if (updateWhenChanged != value)
{
SetBrowsableAttributeValue(nameof(SheathingType), value);
updateWhenChanged = value;
}
}
}
private void SetBrowsableAttributeValue(string attribute, object value)
{
var descriptor = TypeDescriptor.GetProperties(GetType())[attribute];
var attrib = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
var isBrow = attrib.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
isBrow.SetValue(attrib, value);
}
来源:https://stackoverflow.com/questions/31321637/changing-browsable-attribute-at-runtime-c