Introduction
Download sourcecode
Download demo project
One of my favorite controls shipped with .Net, is the property grid. It is extremely powerful, but raises a few challenges when it comes to customizing it.
I recently finished an application that used the propertygrid to manage a rather complex configuration.
Using the propertygrid along with XML serialization is a very simple, yet effective way to implement complex configuration scenarios.
Just as the application was set to be kicked out the door, I noticed that my property grid did not look as cool as the one in the Visual Studio IDE.
So I spent I few hours trying to get it right.
First of all is the little toolbar at the top displaying icons for sorting and so on.
Why can't I have that nice gradient toolbar in my propertygrid?
Another thing I noticed was that there was no way to make the collection editor display the property description at the bottom as the the propertygrid do.
And the last thing I wanted to fix was the Toolstrip. I wanted that one to have the VS2005 look as well
I wanted to have something like this.

Changing the colors
As for the colors used on the propertygrid toolbar and the toolstrip, the solution was really simple. As I thought maybe I had to do my own painting, all I did was replacing the colortable used by the control's renderer.
Like this
public class CustomPropertyGrid : PropertyGrid
{
public CustomPropertyGrid()
{
[BLOCKQUOTE dir=ltr style=MARGIN-RIGHT: 0px">this.ToolStripRenderer = new ToolStripProfessionalRenderer(new CustomColorTable());
[/B>}
The Custom Colortable is inherited from the ToolStripProfessionalRenderer and just overrides
the properties describing the colors used in each element of the ex Toolstrip.
Displaying the property description in the collection editor.
This is how the collection editor is displayed when used "out of the box"

This is the result after doing some tweaks

The code
The solution to this problem was to do a little reflection to get a reference to the collection editor's form and propertygrid.
protected override CollectionForm CreateCollectionForm()
{
CollectionEditor.CollectionForm form = base.CreateCollectionForm();
form.StartPosition = FormStartPosition.CenterParent;
Type formType = form.GetType();
FieldInfo fieldInfo = formType.GetField("propertyBrowser", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
PropertyGrid propertyGrid = (PropertyGrid)fieldInfo.GetValue(form);
if (propertyGrid != null)
{
propertyGrid.ToolbarVisible = true;
propertyGrid.HelpVisible = true;
Type propertyGridType = propertyGrid.GetType();
PropertyInfo propertyInfo = propertyGridType.GetProperty("ToolStripRenderer",BindingFlags.NonPublic | BindingFlags.Instance);
if (propertyInfo != null)
{
propertyInfo.SetValue(propertyGrid,new ToolStripProfessionalRenderer(new CustomColorTable()),null);
}
}
}
return form;
}
As you may notice the custom renderer is also applied to the collection editor's propertygrid.
Using the custom collection editor
[Editor(typeof(CustomCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List<Employee> Employees
{
get { return mEmployees; }
set { mEmployees = value; }
}
Now my application looks like it should and everybody is happy, including me.
|
|
 |
 | My vote of 2 V# Guy | 17:17 3 Feb '09 |
|
|
 |
 | How can I attach event to CustomCollectionEditor? connectpalm | 1:16 20 Dec '07 |
|
 |
Firstly, Thanks for the excellent input of using reflection to custonmize the collectioneditor. In one of the threads, as you have already given the details on how to get the add and remove button. I use the same and would like to take it a step further where I can attach events to the add, remove, ok and cancel buttons. I was able to add them with out any problems.
//... public event EventHandler OnCollectionAddButtonClicked;
//.... // the add button FieldInfo addButtonInfo = formType.GetField("addButton", BindingFlags.NonPublic | BindingFlags.Instance); if (null != addButtonInfo) { Button addButton = (Button)addButtonInfo.GetValue(form); addButton.Enabled = this.EnableAddButton; addButton.Click += new EventHandler(this.CollectionAddButton_Clicked); }
//... private void CollectionAddButton_Clicked(Object sender, EventArgs e) { if (this.OnCollectionAddButtonClicked != null ) this.OnCollectionAddButtonClicked.Invoke(sender, e); }
So far so good. I use this editor in the example given by you [Editor(typeof(CustomCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))] public List<Employee> Employees { get { return mEmployees; } set { mEmployees = value; } }
But how can I attach the event handler such that I receive the event when the user has added an employee?? something like CustomCollectionEditor editor = new CustomCollectionEditor(System.Drawing.Design.UITypeEditor); editor.OnCollectionAddButtonClicked += new EventHandler(this.OnEmployeeAdded);
[Editor(typeof(editor), typeof(System.Drawing.Design.UITypeEditor))] public List&lt;Employee&gt; Employees { get { return mEmployees; } set { mEmployees = value; } }
But this doesn't work, i am now stuck at this last place?? any help is highly appreciated. thanks in advance
Vishnu
|
|
|
|
 |
 | How I can make it? [modified] agorby | 3:00 30 Oct '07 |
|
 |
I know, that is ordinary question ("gridView" is standard field of PropertyGrid) for you. Please, help me get access to the FieldInfo from underlying PropertyGrid from your VS2005 PropertyGrid, i.e. I try so:
PropertyGrid propertyGrid = (PropertyGrid)propertyGrid2005; Type type = propertyGrid.GetType(); FieldInfo field = type.GetField("gridView", BindingFlags.NonPublic | BindingFlags.Instance);
but "field" is null. Why?
-- modified at 8:33 Tuesday 30th October, 2007
|
|
|
|
 |
|
 |
Hi agorby,
As wrote in this article, the property grid is not the standard one (eg. "System.Windows.Forms.PropertyGrid") but a "System.Windows.Forms.Design.VsPropertyGrid" which is not usable "as is".
I think that's why you can't get the internal "gridView" or "categoryForeColor" field info.
I continue my investigation, because I've the same need . Let me know if you've found a work-around.
G.
|
|
|
|
 |
 | Re: How I can make it? agorby | 5:56 30 Nov '07 |
|
 |
Thank you
|
|
|
|
 |
 | Almost! thany.org | 5:32 7 Sep '07 |
|
 |
The VS2005 toolstrip in the demo application appears yellowish, so it seems as if it's based on a hard-coded color. In reality, the color of toolstrips and such is based on SystemColors.Control, so in my case it should appear gray, because SystemColors.Color==Color.Silver on my system. But really it could be anything
-- Thany
|
|
|
|
 |
 | ReadOnly Collection kembo | 6:38 11 Jun '07 |
|
 |
How can you make the collection readonly so that the popup has the 'Add' and 'Remove' buttons disabled?
|
|
|
|
 |
|
 |
Hi kembo,
You can use the following code :
CollectionEditor.CollectionForm form = base.CreateCollectionForm();
Type formType = form.GetType();
FieldInfo addButtonInfo = formType.GetField("addButton", BindingFlags.NonPublic | BindingFlags.Instance); if(null != addButtonInfo ) { Button addButton= (Button)addButtonInfo .GetValue(form); addButton.Enabled = false; }
FieldInfo removeButtonInfo = formType.GetField("removeButton", BindingFlags.NonPublic | BindingFlags.Instance); if(null != removeButtonInfo) { Button removeButton = (Button)removeButtonInfo.GetValue(form); removeButton.Enabled = false; }
Hope this helps, G.
|
|
|
|
 |
 | Example does not use CustomCollectionEditor SteveC | 2:04 1 May '07 |
|
 |
One *very* minor comment.
In the demo/source you provided, you ommitted the code to actually use the "CustomCollectionEditor".
[Editor(typeof(CustomCollectionEditor), typeof(System.Drawing.Design.UITypeEditor))] // is missing public List Employees { get { return mEmployees; } set { mEmployees = value; } }
I dont know if this was by intention....
Either way a really helpful article.
Thanks
|
|
|
|
 |
 | Nice chris175 | 8:51 16 Jan '07 |
|
 |
Just what I was looking for. I needed a collection editor with descriptions. Is there any way to put custom validation on inputs in a collection editor? If so how can you?
Chris
|
|
|
|
 |
 | Cool -- Is it OK to use VS2005Components? Stephen Lamb | 20:20 14 Sep '06 |
|
 |
Cool article.
Is it really OK to use VS2005Components? Isn't this a MS proprietary assembly?
|
|
|
|
 |
|
 |
No, it is not
I packed this components into an assembly as I use it in several projects
As you can see it's not complicated at all. It's just the CustomCollectionEditor that has some code to get a reference to the toolstrip.
And you are certainly free to use it
Regards
//seesharper
|
|
|
|
 |
 | Very good. Now Could you? Pink Floyd | 7:45 22 May '06 |
|
 |
Hi SeeSharper, First, very good article, thanks for sharing.
Now, I think that maybe you could throw some light into a serious problem, maybe a VS.NET 2005 IDE bug. Your experience and knowledge of the Property Editors could save the day.
Please read this and let me know about any findings or ideas, I'd really really appreciate it.
http://www.codeproject.com/script/comments/forums.asp?msg=1472177&forumid=1649#xx1472177xx[^]
Of course, everyone is invited
Thanks a lot in advance.
|
|
|
|
 |
 | Thanx! Nice Life | 0:12 16 May '06 |
|
 |
Great work! Just what I was looking for...
Have a nice life!!
|
|
|
|
 |
|
|
Last Updated 11 May 2006 |
Advertise |
Privacy |
Terms of Use |
Copyright ©
CodeProject, 1999-2010