I want to change the Text in the Help area in WinForm PropertyGrid after the PropertyGrid is load. Here is my 2 attempts using reflection, but they both not working correctly.
Solution 1: I inherited the PropertyGrid and retrieve the doccomment, which is the control for the Help area. I have a separate button that calls the ChangeHelpText method to change the text property of doccomment. After it, I then call the Refresh method of the PropertyGrid. However, nothing changes. Also I assign HelpBackColor of the PropertyGrid, nothing changes as well. Any idea?
public void ChangeHelpText(String desc)
{
FieldInfo fi = this.GetType().BaseType.GetField("doccomment", BindingFlags.NonPublic | BindingFlags.Instance);
Control dc = fi.GetValue(this) as Control;
dc.Text = desc;
dc.BackColor = Color.AliceBlue;
fi.SetValue(this, dc);
}
Solution 2: The PropertyGrid's Help text reflects the DescriptionAttribute of the properties in the binding class. Therefor I use TypeDescriptor.GetProperties to retrieve all properties of the SelectedObject of the PropertyGrid, loop through them and retrieve the DescriptionAttribute, and change the description private field of the DescriptionAttribute to my text using reflection. Interestingly, if I put a break point where I reassign the DescriptionAttribute, this solution works partially as only some properties' DescriptionAttribute are changed and reflected in the PropertyGrid and others are not changed. If I don't put the breakpoint, nothing is changed. Everything is running in the STAThread.
The first solution doesn't work because you are setting the control's Text
property which is not used for displaying the help text. The DocComment
control has two label child controls which is used for displaying the help title (property label) and help text (property description attribute value). If you want to change the help text you have manipulate these two labels.
It is simpler to just call the method which updates these two controls. The sample code given below works but uses reflection to invoke the method.
public class CustomPropertyGrid : PropertyGrid
{
Control docComment = null;
Type docCommentType = null;
public void SetHelpText(string title, string helpText)
{
if (docComment == null)
{
foreach (Control control in this.Controls)
{
Type controlType = control.GetType();
if (controlType.Name == "DocComment")
{
docComment = control;
docCommentType = controlType;
}
}
}
BindingFlags aFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
MethodInfo aInfo = docCommentType.GetMethod("SetComment", aFlags);
if (aInfo != null)
{
aInfo.Invoke(docComment, new object[] { title, helpText });
}
}
}
To change the back color and fore color use the properties provided by the PropertyGrid
.
propertyGrid1.HelpBackColor = Color.BlueViolet;
propertyGrid1.HelpForeColor = Color.Yellow;