Any class or property can have an EditorAttribute.
When an object is displayed in the PropertyGrid, the attributes are read to
see if a specific editor is assigned.
The basic types have simple type converters that convert from string to
value so that you can type "100,50" in a Size property for example.
Other types, such as the Form.DockStyle have a UITypeEditor that is a
dropdown control. Collections have a UITypeEditor that appears as a modal
dialog. All types will have a default editor that is more or less
specialized for that type.
You can create a UITypeEditor quite simply.
Step 1. Create a control that edits a single value, for example a Color. It
should accept a value and display it, enable the user to modify it and then
return the modified value after.
Step2. Create an editor based on UITypeEditor. In the EditValue override
invoke your control
Step3. Add the EditorAttribute to your property so that the PropertyGrid
knows which one to use.
After my signature is an application that demonstrates how to create a
UITypeEditor and assign it to a property. Editing Thing2's Color property
uses a non-standard Color UITypeEditor. See how Thing2 assigns an editor.
--
Bob Powell [MVP]
C#, System.Drawing
September's edition of Well Formed is now available.
http://www.bobpowell.net/currentissue.htm
Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm
---------------------------
using System;
using System.Drawing;
using System.Drawing.Design;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Data;
namespace NewColorEditor
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.PropertyGrid propertyGrid1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
Thing1 t1 =new Thing1();
Thing2 t2 =new Thing2();
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// propertyGrid1
//
this.propertyGrid1.Anchor =
((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.To
p | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.propertyGrid1.CommandsVisibleIfAvailable = true;
this.propertyGrid1.LargeButtons = false;
this.propertyGrid1.LineColor = System.Drawing.SystemColors.ScrollBar;
this.propertyGrid1.Location = new System.Drawing.Point(160, 0);
this.propertyGrid1.Name = "propertyGrid1";
this.propertyGrid1.Size = new System.Drawing.Size(130, 264);
this.propertyGrid1.TabIndex = 0;
this.propertyGrid1.Text = "propertyGrid1";
this.propertyGrid1.ViewBackColor = System.Drawing.SystemColors.Window;
this.propertyGrid1.ViewForeColor =
System.Drawing.SystemColors.WindowText;
//
// button1
//
this.button1.Location = new System.Drawing.Point(40, 56);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "Thing 1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(40, 120);
this.button2.Name = "button2";
this.button2.TabIndex = 2;
this.button2.Text = "Thing 2";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.propertyGrid1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
this.propertyGrid1.SelectedObject=t1;
}
private void button2_Click(object sender, System.EventArgs e)
{
this.propertyGrid1.SelectedObject=t2;
}
}
/// <summary>
/// Summary description for UserControl1.
/// </summary>
public class UserControl1 : System.Windows.Forms.UserControl
{
Color _color;
public Color Color
{
get{return _color;}
set
{
_color=value;
this.trackBar1.Value=value.R;
this.trackBar2.Value=value.G;
this.trackBar3.Value=value.B;
this.BackColor=value;
}
}
private System.Windows.Forms.TrackBar trackBar1;
private System.Windows.Forms.TrackBar trackBar2;
private System.Windows.Forms.TrackBar trackBar3;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public UserControl1()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.trackBar1 = new System.Windows.Forms.TrackBar();
this.trackBar2 = new System.Windows.Forms.TrackBar();
this.trackBar3 = new System.Windows.Forms.TrackBar();
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.trackBar2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.trackBar3)).BeginInit();
this.SuspendLayout();
//
// trackBar1
//
this.trackBar1.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left
| System.Windows.Forms.AnchorStyles.Right)));
this.trackBar1.LargeChange = 8;
this.trackBar1.Location = new System.Drawing.Point(0, 0);
this.trackBar1.Maximum = 255;
this.trackBar1.Name = "trackBar1";
this.trackBar1.Size = new System.Drawing.Size(178, 45);
this.trackBar1.TabIndex = 0;
this.trackBar1.TickFrequency = 8;
this.trackBar1.Scroll += new
System.EventHandler(this.trackBar_Scroll);
//
// trackBar2
//
this.trackBar2.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left
| System.Windows.Forms.AnchorStyles.Right)));
this.trackBar2.LargeChange = 8;
this.trackBar2.Location = new System.Drawing.Point(0, 48);
this.trackBar2.Maximum = 255;
this.trackBar2.Name = "trackBar2";
this.trackBar2.Size = new System.Drawing.Size(178, 45);
this.trackBar2.TabIndex = 0;
this.trackBar2.TickFrequency = 8;
this.trackBar2.Scroll += new
System.EventHandler(this.trackBar_Scroll);
//
// trackBar3
//
this.trackBar3.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left
| System.Windows.Forms.AnchorStyles.Right)));
this.trackBar3.LargeChange = 8;
this.trackBar3.Location = new System.Drawing.Point(0, 96);
this.trackBar3.Maximum = 255;
this.trackBar3.Name = "trackBar3";
this.trackBar3.Size = new System.Drawing.Size(178, 45);
this.trackBar3.TabIndex = 0;
this.trackBar3.TickFrequency = 8;
this.trackBar3.Scroll += new
System.EventHandler(this.trackBar_Scroll);
//
// UserControl1
//
this.Controls.Add(this.trackBar1);
this.Controls.Add(this.trackBar2);
this.Controls.Add(this.trackBar3);
this.Name = "UserControl1";
this.Size = new System.Drawing.Size(176, 150);
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.trackBar2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.trackBar3)).EndInit();
this.ResumeLayout(false);
}
#endregion
private void trackBar_Scroll(object sender, System.EventArgs e)
{
_color=Color.FromArgb(this.trackBar1.Value,this.trackBar2.Value,this.trackBa
r3.Value);
this.BackColor=_color;
}
}
public class Thing1
{
Point _point;
public Point Point
{
get{return _point;}
set{_point=value;}
}
Color _color=Color.Blue;
public Color Color
{
get{return _color;}
set{_color=value;}
}
}
public class Thing2
{
Size _size;
public Size Size
{
get{return _size;}
set{_size=value;}
}
int _integer;
public int Integer
{
get{return _integer;}
set{_integer=value;}
}
Color _color=Color.Red;
[Editor(typeof(ColorSliderEditor),typeof(UITypeEditor))]
public Color Color
{
get{return _color;}
set{_color=value;}
}
}
class ColorSliderEditor : UITypeEditor
{
public override UITypeEditorEditStyle
GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
IWindowsFormsEditorService
edsvc=(IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEd
itorService));
if(edsvc!=null)
{
UserControl1 uc=new UserControl1();
uc.Color=(Color)value;
edsvc.DropDownControl(uc);
return uc.Color;
}
return value;
}
public override bool GetPaintValueSupported(ITypeDescriptorContext
context)
{
return true;
}
public override void PaintValue(PaintValueEventArgs e)
{
SolidBrush b=new SolidBrush((Color)e.Value);
e.Graphics.FillRectangle(b,e.Bounds);
b.Dispose();
}
}
}
---------------------------
babylon said:
How does TreeNodeCollection be different so that VS.NET will bring up a
TreeNode Editor with it?
thx