Introduction
When working with controls like grids etc., it is much easier to design the GUI if we can see the data filled grid, and then adjust the various look and feel properties. Similarly, there are several other places where we able to change properties and watch their effects during run time.
Background
It all started while I was trying to configure a multi level data grid/tree control. I found that whatever I was doing during the design time does not reflect the runtime behavior when the control is populated with data. I started researching the PropertyGrid
control, and came up with this control.
Using the code
Include the control PropertyEditor
in the tool box by browsing to the WYSIWYGFormEditor.dll and adding it to the .NET Framework Components window.
Create a form frmProperties
and add this control to it. On your main form, which have the controls needing design, add a Button
and invoke the frmProperties
form.
private void button1_Click(object sender, System.EventArgs e) {
frmProperties frmprop = new frmProperties();
frmprop.LoadChildControls(this);
frmprop.Show();
}
LoadChildControls
loads all the current controls on the form into the PropertyGrid
. If you need to work with a single control, or a subset of controls, then just add the container containing the relevant controls.
public void LoadChildControls(Control parentCtrl){
if(parentCtrl.Controls.Count == 0){
if(!comboBox1.Items.Contains(parentCtrl)){
comboBox1.Items.Add(parentCtrl);
comboBox1.SelectedItem = parentCtrl;
}
}
else{
foreach(Control ctrl in parentCtrl.Controls){
LoadChildControls(ctrl);
}
}
}
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace WYSIWYGFormEditor
{
public class PropertyEditor : System.Windows.Forms.UserControl
{
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.GroupBox Properties;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.PropertyGrid propertyGrid1;
private System.ComponentModel.IContainer components;
public PropertyEditor()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.Properties = new System.Windows.Forms.GroupBox();
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
this.Properties.SuspendLayout();
this.SuspendLayout();
this.comboBox1.Dock = System.Windows.Forms.DockStyle.Top;
this.comboBox1.Location = new System.Drawing.Point(3, 16);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(290, 21);
this.comboBox1.TabIndex = 0;
this.comboBox1.SelectedIndexChanged +=
new System.EventHandler(this.comboBox1_SelectedIndexChanged);
this.Properties.Controls.Add(this.propertyGrid1);
this.Properties.Controls.Add(this.comboBox1);
this.Properties.Dock = System.Windows.Forms.DockStyle.Left;
this.Properties.Location = new System.Drawing.Point(0, 0);
this.Properties.Name = "Properties";
this.Properties.Size = new System.Drawing.Size(296, 352);
this.Properties.TabIndex = 2;
this.Properties.TabStop = false;
this.Properties.Text = "Properties";
this.propertyGrid1.CommandsVisibleIfAvailable = true;
this.propertyGrid1.Cursor = System.Windows.Forms.Cursors.HSplit;
this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.propertyGrid1.LargeButtons = false;
this.propertyGrid1.LineColor = System.Drawing.SystemColors.ScrollBar;
this.propertyGrid1.Location = new System.Drawing.Point(3, 45);
this.propertyGrid1.Name = "propertyGrid1";
this.propertyGrid1.Size = new System.Drawing.Size(290, 304);
this.propertyGrid1.TabIndex = 1;
this.propertyGrid1.Text = "propertyGrid1";
this.propertyGrid1.ViewBackColor =
System.Drawing.SystemColors.Window;
this.propertyGrid1.ViewForeColor =
System.Drawing.SystemColors.WindowText;
this.Controls.Add(this.Properties);
this.Name = "PropertyEditor";
this.Size = new System.Drawing.Size(296, 352);
this.Resize += new System.EventHandler(this.PropertyEditor_Resize);
this.Properties.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
public void DesignControl(Control ctrl){
foreach(Control Child in ctrl.Controls){
this.comboBox1.Items.Add(Child);
}
}
private void comboBox1_SelectedIndexChanged(object sender,
System.EventArgs e) {
propertyGrid1.SelectedObject = comboBox1.SelectedItem as Control;
}
public void LoadChildControls(Control parentCtrl){
if(parentCtrl.Controls.Count == 0){
if(!comboBox1.Items.Contains(parentCtrl)){
comboBox1.Items.Add(parentCtrl);
comboBox1.SelectedItem = parentCtrl;
}
}
else{
foreach(Control ctrl in parentCtrl.Controls){
LoadChildControls(ctrl);
}
}
}
}
}
Points of Interest
Possible extension of this project:
- Record all the changes, and let the user define the ones they like.
- On close of the form, save these change into
ClipBoard
and let the user paste it into the code. I have left some remnants of this functionality uncompleted in the code.. Want to try?