How to 'open' TreeNode Editor

B

babylon

I found that if my custom control have a public property of a
String array, it will open a String collection editor, and for
Object array, it will open an object collection editor,

What type of property do I need to have in order to open a TreeNode Editor?

thx!
 
A

Action

I think he wants to write his own TreeNodeCollection
so what 'interfaces' does a class provide in order to let VS.Net open a
treenode editor.
 
B

babylon

How does TreeNodeCollection be different so that VS.NET will bring up a
TreeNode Editor with it?

thx
 
B

Bob Powell [MVP]

The TreeNodeCollection already has an editor associated with it. If you use
TreeNodeCollection as a property, you'll be able to edit them with that
editor.

If you want to create another editor for a standard TreeNodeCollection or
some other collection, you need to write an editor based on UITypeEditor and
use the EditorAttribute on the property or at the class level to invoke it.

--
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
 
B

Bob Powell [MVP]

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();

}









}



}
 
B

babylon

thx!
very detailed help!!!

Bob Powell said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top