WYSIWYG Runtime Properties Editor

Introduction

When working with controls such as grids and so forth, 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 when 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 PropertyEditor control in the tool box by browsing to the WYSIWYGFormEditor.dll and adding it to the .NET Framework Components window.

private void button1_Click(object sender, System.EventArgs e) {

    frmProperties frmprop = new frmProperties();
    //Load all the controls into the property grid
    frmprop.LoadChildControls(this);
    //Show the form with propertygrid
    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, just add the container containing the relevant controls.

//This is a recursive function to load all the child controls
//within child controls....
public void LoadChildControls(Control parentCtrl){
    if(parentCtrl.Controls.Count == 0){
    //no more child controls so load this and return
        if(!comboBox1.Items.Contains(parentCtrl)){
            comboBox1.Items.Add(parentCtrl);
            comboBox1.SelectedItem = parentCtrl;
        }
    }
    else{
    //has more child controls.. call recursively
        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
{
    /// <summary>
    /// A control to help Visual editing of properties
    /// and seeing the effects of it in run time.
    /// </summary>
    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()
        {
            // This call is required by the Windows.Forms Form
            // Designer.
            InitializeComponent();

            // TODO: Add any initialization after the
            // 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 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.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();
            //
            // comboBox1
            //
            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);
            //
            // Properties
            //
            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";
            //
            // propertyGrid1
            //
            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;
            //
            // PropertyEditor
            //
            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;
        }

        //This is a recursive function to load all the child
        //controls within child controls....
            public void LoadChildControls(Control parentCtrl){
            if(parentCtrl.Controls.Count == 0){
            //no more child controls so load this and return
                if(!comboBox1.Items.Contains(parentCtrl)){
                    comboBox1.Items.Add(parentCtrl);
                    comboBox1.SelectedItem = parentCtrl;
                }
            }
            else{
            //has more child controls... call recursively
                foreach(Control ctrl in parentCtrl.Controls){
                    LoadChildControls(ctrl);
                }
            }
        }
    }
}

Points of Interest

Possible extensions of this project:

  1. Record all the changes, and let the user define the ones they like.
  2. 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?


About the Author

Mind Experts

Our Web Site

Comments

  • Hi

    Posted by thminhle on 02/20/2008 03:44am

    Hello

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: September 16, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you starting an on-premise-to-cloud data migration project? Have you thought about how much space you might need for your online platform or how to handle data that might be related to users who no longer exist? If these questions or any other concerns have been plaguing you about your migration project, check out this eSeminar. Join our speakers Betsy Bilhorn, VP, Product Management at Scribe, Mike Virnig, PowerSucess Manager and Michele …

  • For the third consecutive year, Neustar surveyed hundreds of companies on distributed denial of service (DDoS) attacks. Neustar's survey reveals evidence that the DDoS attack landscape is changing. The number of companies attacked is up, but attack duration is down. Larger attacks are more common, but most attacks are still less than 1 Gbps. More than half of attacked companies reported theft of funds, data or intellectual property. Read the full report to learn how DDoS attacks have evolved in both strategy …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds