Click here to Skip to main content
15,881,803 members
Articles / Multimedia / GDI+

100% Reflective Class Diagram Creation Tool

Rate me:
Please Sign up or sign in to vote.
4.98/5 (498 votes)
14 Jun 2011CPOL28 min read 1.8M   39.6K   1.2K  
100% Reflective Class Diagram Creation Tool
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

using Reflector.CodeModel;


namespace AutoDiagramer
{


    #region DrawableClass CLASS
    /// <summary>
    /// Provides the analysis and rendering of everything that is required
    /// to completely reverse engineer a single Type, and to draw this as
    /// a class on a class diagram.
    /// </summary>
    public partial class DrawableClass : UserControl
    {
        #region Instance fields
        //private instance fields
        private string _Name = "";
        private List<string> _Constructors = new List<string>();
        private List<string> _Fields = new List<string>();
        private List<string> _Properties = new List<string>();
        private List<string> _Interfaces = new List<string>();
        private List<string> _Methods = new List<string>();
        private List<string> _Events = new List<string>();
        private List<string> _Associations = new List<string>();
        private ITypeDeclaration _type_to_Draw_Reflector;
        private Type _type_to_Draw;
        private Label[] _lbls;
        private Font _rowFont;
        private Font _titleFont;
        private int _interfaces_X_End_Pos = 0;
        private int _interfaces_Y_End_Pos = 0;
        private Expander _ucConstructors=null;
        private Expander _ucFields = null;
        private Expander _ucProperties = null;
        private Expander _ucMethods = null;
        private Expander _ucEvents = null;
        private PictureBox _picMainExpander = null;
        private int _expanderSize = 13;
        private int _genericSpaceSizeH = 6;
        private int _genericSpaceSizeV = 10;
        private int _EndSpacerSize = 40;
        private int _interfaceDrawingLineStart = 0;
        private int _interfaceDrawingLineEnd = 0;
        private int _MainBodyRenderStart = 0;
        private int _MainBodyBorderWidth = 2;
        private Color _ClassStartColor = Color.LightGray;
        private Color _ClassEndColor = Color.White;
        private Color _ClassBorderColor = Color.SteelBlue;
        private States _currentState = States.Expanded;
        private int _ConstructorsOldHeight = 0;
        private int _FieldsOldHeight = 0;
        private int _PropertiesOldHeight = 0;
        private int _MethodsOldHeight = 0;
        private int _EventsOldHeight = 0;
        private bool _latchedIn = false;
        private int _ContainerRow = 0;
        private int _ContainerColumn = 0;
        private int _FullExpandedHeight = 0;
        //public instance fields
        public enum States { Collapsed, PartiallyCollasped, Expanded };
        public delegate void SizeStateChangedEventHandler(object sender, SizeEventArgs args);
        public event SizeStateChangedEventHandler SizeChanged;


        #endregion
        #region Ctor
        /// <summary>
        /// Stores the type provided as an internal field and
        /// calls the AnalyseType() internal method. And also
        /// creates several <see cref="Expander">Expander </see>
        /// controls to diplay the individual Properties,Events,Fields,
        /// Constructors,Methods details. Finally an overall
        /// collapse / expand image is created
        /// </summary>
        /// <param name="t">The Type to analyze</param>
        public DrawableClass(ITypeDeclaration t)
        {
            this.InitializeComponent();

            //set to flickerless style
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.UserPaint, true);

			this._type_to_Draw_Reflector = t;
			this._Name = t.Name;
			this._rowFont = new Font("Microsoft Sans Serif", 8.25F);
			this._titleFont = new Font("Microsoft Sans Serif", 8.25F, FontStyle.Bold);
            this.BorderStyle = BorderStyle.None;
            this.Width = 5;
            this.Height = 5;

            try
            {
                //begin analysis
                AnalyseTypeReflector();
                commonUICodeSetup();
            }
            catch (Exception ex)
            {
                Program.ErrorBox(ex.Message);
            }
        }

        private void commonUICodeSetup()
        {
               #region Create Expander controls for Methods, Properties etc etc
                //create interface drawing items
                if (_Interfaces.Count > 0) {
                    showInterfaces();
                }
                //create Constructor drawing items
                if (_Constructors.Count > 0)
                {
                    _ucConstructors = new 
                        Expander("Constructors", Expander.PossibleTypes.Constructors);
                    _ucConstructors.RowContent = _Constructors;
                    _ucConstructors.PanelStateChanged += 
                        new Expander.PanelStateChangedEventHandler(_Expander_PanelStateChanged);
                }
                //create Fields drawing items
                if (_Fields.Count > 0)
                {
                    _ucFields = new
                        Expander("Fields", Expander.PossibleTypes.Fields);
                    _ucFields.RowContent = _Fields;
                    _ucFields.PanelStateChanged +=
                        new Expander.PanelStateChangedEventHandler(_Expander_PanelStateChanged);

                }
                //create Properties drawing items
                if (_Properties.Count > 0)
                {
                    _ucProperties = new
                        Expander("Properties", Expander.PossibleTypes.Properties);
                    _ucProperties.RowContent = _Properties;
                    _ucProperties.PanelStateChanged +=
                        new Expander.PanelStateChangedEventHandler(_Expander_PanelStateChanged);
                }
                //create Methods drawing items
                if (_Methods.Count > 0)
                {
                    _ucMethods = new
                        Expander("Methods", Expander.PossibleTypes.Methods);
                    _ucMethods.RowContent = _Methods;
                    _ucMethods.PanelStateChanged +=
                        new Expander.PanelStateChangedEventHandler(_Expander_PanelStateChanged);
                }
                //create Events drawing items
                if (_Events.Count > 0)
                {
                    _ucEvents = new
                        Expander("Events", Expander.PossibleTypes.Events);
                    _ucEvents.RowContent = _Events;
                    _ucEvents.PanelStateChanged +=
                        new Expander.PanelStateChangedEventHandler(_Expander_PanelStateChanged);
                }
                #endregion
                //main expander picture box
                _picMainExpander = new PictureBox();
                _picMainExpander.Name = "picExpander";
                _picMainExpander.Image = global::AutoDiagramer.Resource1.MainCollapse13;
                _picMainExpander.Width = _expanderSize;
                _picMainExpander.Height = _expanderSize;
                _picMainExpander.Click += new EventHandler(_picMainExpander_Click);
                //have to wait to add the expander picture box, as its loction is determined
                //by RegenerateControl(), so call that 1st
                RegenerateControl();
                ChangeStateOfControl();
                //then add the expander picture box
                this.Controls.Add(_picMainExpander);
        }


        /// <summary>
        /// Stores the type provided as an internal field and
        /// calls the AnalyseType() internal method. And also
        /// creates several <see cref="Expander">Expander </see>
        /// controls to diplay the individual Properties,Events,Fields,
        /// Constructors,Methods details. Finally an overall
        /// collapse / expand image is created
        /// </summary>
        /// <param name="t">The Type to analyze</param>
        public DrawableClass(Type t)
        {
            this.InitializeComponent();

            //set to flickerless style
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.UserPaint, true);

			this._type_to_Draw = t;
			this._Name = t.Name;
			this._rowFont = new Font("Microsoft Sans Serif", 8.25F);
			this._titleFont = new Font("Microsoft Sans Serif", 8.25F, FontStyle.Bold);
            this.BorderStyle = BorderStyle.None;
            this.Width = 5;
            this.Height = 5;

            try
            {
                //begin analysis
                AnalyseType();
                commonUICodeSetup();
            }
            catch (Exception ex)
            {
                Program.ErrorBox(ex.Message);
            }
        }




        /// <summary>
        /// Determines which state should be the new overall state
        /// </summary>
        /// <param name="sender">the _picMainExpander</param>
        /// <param name="e">the events args</param>
        private void _picMainExpander_Click(object sender, EventArgs e)
        {
            ChangeStateOfControl();
        }

        /// <summary>
        /// Changes the current state of the control (expanded / collapsed)
        /// </summary>
        private void ChangeStateOfControl()
        {
            if (_currentState == States.Expanded)
            {
                _currentState = States.Collapsed;
            }
            else if (_currentState == States.Collapsed || _currentState == States.PartiallyCollasped)
            {
                _currentState = States.Expanded;
            }

            switch (_currentState)
            {
                case States.Expanded:
                case States.PartiallyCollasped:
                    this._picMainExpander.Image = global::AutoDiagramer.Resource1.MainCollapse13;
                    showExpanders(true);
                    RegenerateControl();
                    break;

                case States.Collapsed:
                    this._picMainExpander.Image = global::AutoDiagramer.Resource1.MainExpand13;
                    showExpanders(false);
                    RegenerateControl();
                    break;
            }

            // If anyone has subscribed, notify them
            OnSizeChanged(this, new SizeEventArgs(this));
        }


        /// <summary>
        /// Shows or hides the Expander control parameter provided.
        /// In the case of showing, the height parameter is used for
        /// the height of the Expander
        /// </summary>
        /// <param name="visible">true to show the expander</param>
        /// <param name="expander">the expander to show/hide</param>
        /// <param name="old_expanderHeight">the old expander controls height</param>
        private void setExpanderState(bool visible, Expander expander, int old_expanderHeight)
        {
            if (expander != null)
            {
                if (!visible)
                {
                    expander.Height = 0;
                }
                else
                {
                    expander.Height = old_expanderHeight;
                }
            }
        }

        /// <summary>
        /// if the visible parameter is true show ucExander controls
        /// </summary>
        /// <param name="visible">true means shown ucExander controls</param>
        private void showExpanders(bool visible)
        {
            //create Constructor height
            setExpanderState(visible, _ucConstructors, _ConstructorsOldHeight);
            //create Fields height
            setExpanderState(visible, _ucFields, _FieldsOldHeight);
            //create Properties height
            setExpanderState(visible, _ucProperties, _PropertiesOldHeight);
            //create Methods height
            setExpanderState(visible, _ucMethods, _MethodsOldHeight);
            //create Events height
            setExpanderState(visible, _ucEvents, _EventsOldHeight);
        }

        /// <summary>
        /// Raised when one of the Expander controls changes state. Will also
        /// change the current state of this control and will raise the 
        /// OnSizeChanged() event
        /// </summary>
        /// <param name="sender">The current Expander control</param>
        /// <param name="args"></param>
        private void _Expander_PanelStateChanged(object sender, ExpanderSizeEventArgs args)
        {

            RegenerateControl();
            if (args.CurrentState== Expander.States.Collapsed)
            {
                this.CurrentState = States.PartiallyCollasped;
            }
            else if (args.CurrentState== Expander.States.Expanded)
            {
                this.CurrentState = States.Expanded;
            }

            // If anyone has subscribed, notify them
            OnSizeChanged(this, new SizeEventArgs(this));
        }
        #endregion
        #region Public Properties
        /// <summary>
        /// gets / sets the border Color to use
        /// </summary>        
        [Category("Appearance")]
        [DefaultValue(typeof(Color))]
        [Browsable(true)]
        public Color ClassBorderColor
        {
            get { return _ClassBorderColor; }
            set { _ClassBorderColor = value; }
        }

        /// <summary>
        /// gets / sets the start Color to use
        /// </summary>  
        [Category("Appearance")]
        [DefaultValue(typeof(Color))]
        [Browsable(true)]
        public Color ClassStartColor
        {
            get { return _ClassStartColor; }
            set { _ClassStartColor = value; }
        }

        /// <summary>
        /// gets / sets the end Color to use
        /// </summary>  
        [Category("Appearance")]
        [DefaultValue(typeof(Color))]
        [Browsable(true)]
        public Color ClassEndColor
        {
            get { return _ClassEndColor; }
            set { _ClassEndColor = value; }
        }


        /// <summary>
        /// gets / sets the title Font to use
        /// </summary>  
        [Browsable(true)]
        public Font TitleFont
        {
            get { return _titleFont; }
            set { _titleFont = value; }
        }

        /// <summary>
        /// gets / sets the row Font to use
        /// </summary>  
        [Browsable(true)]
        public Font RowFont
        {
            get { return _rowFont; }
            set { _rowFont = value; }
        }

        /// <summary>
        /// gets the controls Name to use
        /// NOTE : Hides Control.Name inherited property
        /// </summary>  
        [Browsable(true)]
        public new string Name
        {
            get { return _Name; }
        }

        /// <summary>
        /// gets / sets the fully expanded height for this control
        /// </summary>  
        [Browsable(false)]
        public int FullExpandedHeight
        {
            get { return _FullExpandedHeight; }
            set { _FullExpandedHeight = value; }
        }

        /// <summary>
        /// gets / sets the container row number.
        /// These controls are placed in a container grid control, 
        /// using row / col positions. This is the container grid 
        /// control row position in the grid, which
        /// helps for drawing association lines etc etc
        /// </summary>
        [Browsable(false)]
        public int ContainerRow
        {
            get { return _ContainerRow; }
            set { _ContainerRow = value; }
        }

        /// <summary>
        /// gets / sets the container column number.
        /// These controls are placed in a container grid control, 
        /// using row / col positions. This is the container grid 
        /// control column position in the grid, which
        /// helps for drawing association lines etc etc
        /// </summary>
        [Browsable(false)]
        public int ContainerColumn
        {
            get { return _ContainerColumn; }
            set { _ContainerColumn = value; }
        }

        /// <summary>
        /// gets / sets the list of Constructors for the Type this
        /// control is being used to paint
        /// </summary>  
        [Browsable(false)]
        public List<string> Constructors
        {
            get { return _Constructors; }
        }

        /// <summary>
        /// gets / sets the list of Fields for the Type this
        /// control is being used to paint
        /// </summary>  
        [Browsable(false)]
        public List<string> Fields
        {
            get { return _Fields; }
        }

        /// <summary>
        /// gets / sets the list of Properties for the Type this
        /// control is being used to paint
        /// </summary> 
        [Browsable(false)]
        public List<string> Properties
        {
            get { return _Properties; }
        }

        /// <summary>
        /// gets / sets the list of Interfaces for the Type this
        /// control is being used to paint
        /// </summary> 
        [Browsable(false)]
        public List<string> Interfaces
        {
            get { return _Interfaces; }
        }

        /// <summary>
        /// gets / sets the list of Methods for the Type this
        /// control is being used to paint
        /// </summary> 
        [Browsable(false)]
        public List<string> Methods
        {
            get { return _Methods; }
        }

        /// <summary>
        /// gets / sets the list of Events for the Type this
        /// control is being used to paint
        /// </summary> 
        [Browsable(false)]
        public new List<string> Events
        {
            get { return _Events; }
        }

        /// <summary>
        /// gets / sets the list of Associations for the Type this
        /// control is being used to paint
        /// </summary> 
        [Browsable(false)]
        public List<string> Associations
        {
            get { return _Associations; }
            set { _Associations= value; }
        }

        /// <summary>
        /// gets the current state expanded / collapsed
        /// </summary> 
        [Browsable(false)]
        public States CurrentState
        {
            get  { return this._currentState; }
            set  { _currentState = value; }
        }
        #endregion
        #region Private Methods
        /// <summary>
        /// Raised when the panel changes size (collaped/expanded)
        /// </summary>
        /// <param name="sender"><see cref="DrawableClass">this</see></param>
        /// <param name="e">the event args</param>
        private void OnSizeChanged(object sender, SizeEventArgs args)
        {
            // Check if there are any Subscribers
            if (SizeChanged != null)
            {
                // Call the Event
                SizeChanged(sender, args);
            }
        }

        /// <summary>
        /// Creates the interfaces for this Type and draws them on this controls
        /// client area
        /// </summary>
        private void showInterfaces()
        {
            //Label array ToolBar hold interface labels
            _lbls = new Label[_Interfaces.Count];
            //start location and size
            int yLoc = 0;
            _interfaces_X_End_Pos = this.Height;
            _interfaces_Y_End_Pos = this.Width;

            //create a new row for each row that has been provided in the _Interfaces list
            //will a Label for each row seen
            for (int i = 0; i < _lbls.Length; i++)
            {
                //add the relevant Labels 
                _lbls[i] = new Label();
                _lbls[i].AutoSize = true;
                _lbls[i].Location = new System.Drawing.Point(0, yLoc);
                _lbls[i].Font = _rowFont;
                _lbls[i].TextAlign = ContentAlignment.MiddleLeft;
                _lbls[i].Name = "label" + i;
                _lbls[i].Text = _Interfaces[i].ToString();
                this.Controls.Add(_lbls[i]);
                //work out next Locations, and correct sizes for overall control
                yLoc += _lbls[i].Height;
                if (_lbls[i].Width > _interfaces_X_End_Pos)
                    _interfaces_X_End_Pos = _lbls[i].Width;

                _interfaces_Y_End_Pos += _lbls[i].Height;
            }
        }

        /// <summary>
        /// Calls the getMaxWidth() and getMaxHeight() methods
        /// and causes the control to redraw
        /// </summary>
        public void RegenerateControl()
        {
            this.Width = getMaxWidth();
            this.Height = getMaxHeight();
            this.Invalidate();
            Application.DoEvents();
        }

        /// <summary>
        /// Measures all contenst to see how height this control needs to be
        /// to fit its contents
        /// </summary>
        /// <returns>An int which is the highest height this control needs to be
        /// to fit its contents</returns>
        private int getMaxHeight()
        {
            int MaxHeight = 0;
            Graphics g = this.CreateGraphics();
            //is interface drawing area the widest renderable area
            if (_interfaces_Y_End_Pos > MaxHeight)
            {
                _interfaceDrawingLineStart = _interfaces_Y_End_Pos + 15;
                _interfaceDrawingLineEnd = _interfaces_Y_End_Pos + 30;
                MaxHeight = _interfaceDrawingLineEnd;
                _MainBodyRenderStart = _interfaceDrawingLineEnd;
            }
            //work out where the main expander picture box should be
            int xExanderPos = this.Width - (_genericSpaceSizeH + _expanderSize);
            int yExanderPos = MaxHeight + _genericSpaceSizeH;
            _picMainExpander.Location = new Point(xExanderPos, yExanderPos);

            #region Look at all Expander hieghts
            //space from top to expander + expander size + space to base type +
            //base type text + space to start of Expander controls
            MaxHeight += _genericSpaceSizeV + _expanderSize + _genericSpaceSizeV + _genericSpaceSizeV;
            this.SuspendLayout();
            int borderOffset = (int)_MainBodyBorderWidth/2;

            //see if there is a Constructor Expander control to show
            if (_ucConstructors != null)
            {
                _ucConstructors.Location = new Point(borderOffset, MaxHeight);
                _ucConstructors.Width = this.Width - _MainBodyBorderWidth;
                this.Controls.Add(_ucConstructors);
                MaxHeight += _ucConstructors.Height;
            }
            //see if there is a Fields Expander control to show
            if (_ucFields != null)
            {
                _ucFields.Location = new Point(borderOffset, MaxHeight);
                _ucFields.Width = this.Width - _MainBodyBorderWidth;
                this.Controls.Add(_ucFields);
                MaxHeight += _ucFields.Height;
            }
            //see if there is a Properties Expander control to show
            if (_ucProperties != null)
            {
                _ucProperties.Location = new Point(borderOffset, MaxHeight);
                _ucProperties.Width = this.Width - _MainBodyBorderWidth;
                this.Controls.Add(_ucProperties);
                MaxHeight += _ucProperties.Height;
            }
            //see if there is a Methods Expander control to show
            if (_ucMethods != null)
            {
                _ucMethods.Location = new Point(borderOffset, MaxHeight);
                _ucMethods.Width = this.Width - _MainBodyBorderWidth;
                this.Controls.Add(_ucMethods);
                MaxHeight += _ucMethods.Height;
            }
            //see if there is a Events Expander control to show
            if (_ucEvents != null)
            {
                _ucEvents.Location = new Point(borderOffset, MaxHeight);
                _ucEvents.Width = this.Width - _MainBodyBorderWidth;
                this.Controls.Add(_ucEvents);
                MaxHeight += _ucEvents.Height;
            }
            MaxHeight += _genericSpaceSizeV;
            this.ResumeLayout();
            #endregion
            #region Old heights (for re-eapansion)
            //keep a copy of all the old hieghts for when we need to expand the whole class
            //again
            if (! _latchedIn)
            {
                _FullExpandedHeight = MaxHeight;

                if (_ucConstructors != null) 
                    _ConstructorsOldHeight = _ucConstructors.Height;
                if (_ucProperties != null) 
                    _PropertiesOldHeight = _ucProperties.Height;
                if (_ucFields != null)
                    _FieldsOldHeight = _ucFields.Height;
                if (_ucMethods != null)
                    _MethodsOldHeight = _ucMethods.Height;
                if (_ucEvents != null)
                    _EventsOldHeight = _ucEvents.Height;
                _latchedIn = true;
            }
            #endregion

            //return the MaxWidth
            return MaxHeight;
        }

        /// <summary>
        /// Measures all contenst to see how wide this control needs to be
        /// to fit its contents
        /// </summary>
        /// <returns>An int which is the widest width this control needs to be
        /// to fit its contents</returns>
        private int getMaxWidth()
        {
            int MaxWidth = 0;
            Graphics g = this.CreateGraphics();
            //is interface drawing area the widest renderable area
            if (_interfaces_X_End_Pos > MaxWidth)
            {
                MaxWidth = _interfaces_X_End_Pos;
            }
            //work out title width
            int overallClassTitleAreaWidth = (int)
                //left space before title
                _genericSpaceSizeH +
                //title text
                (int)((SizeF)g.MeasureString(this.Name, _titleFont)).Width +
                //space after title before expander PictureBox
                _genericSpaceSizeH + 
                //expander PictureBox
                _expanderSize +
                //space after expander PictureBox
                _genericSpaceSizeH;
            //is interface drawing area the widest renderable area
            if (overallClassTitleAreaWidth > MaxWidth)
            {
                MaxWidth = overallClassTitleAreaWidth;
            }

 
            if (!Program._isStandAloneApp)
            {
                //Is there a baseclass to render
                if (_type_to_Draw_Reflector.BaseType != null)
                {
                    int baseTypeWidth = _EndSpacerSize +
                    (int)((SizeF)g.MeasureString(_type_to_Draw_Reflector.BaseType.Name, _rowFont)).Width + _EndSpacerSize;
                    if (baseTypeWidth > MaxWidth)
                    {
                        MaxWidth = baseTypeWidth;
                    }
                }
            }
            else 
            {
                //Is there a baseclass to render
                if (_type_to_Draw.BaseType != null)
                {
                    int baseTypeWidth = _EndSpacerSize +
                    (int)((SizeF)g.MeasureString(_type_to_Draw.BaseType.Name, _rowFont)).Width + _EndSpacerSize;
                    if (baseTypeWidth > MaxWidth)
                    {
                        MaxWidth = baseTypeWidth;
                    }
                }
            }

            #region Look at all Expander widths
            //compare it to the constructor expander controls width
            if (_ucConstructors != null)
            {
                //is interface drawing area the widest renderable area
                if (_ucConstructors.Width > MaxWidth)
                {
                    MaxWidth = _ucConstructors.Width;
                }
            }

            //compare it to the Fields expander controls width
            if (_ucFields != null)
            {
                //is interface drawing area the widest renderable area
                if (_ucFields.Width > MaxWidth)
                {
                    MaxWidth = _ucFields.Width;
                }
            }

            //compare it to the Properties expander controls width
            if (_ucProperties != null)
            {
                //is interface drawing area the widest renderable area
                if (_ucProperties.Width > MaxWidth)
                {
                    MaxWidth = _ucProperties.Width;
                }
            }

            //compare it to the Methods expander controls width
            if (_ucMethods != null)
            {
                //is interface drawing area the widest renderable area
                if (_ucMethods.Width > MaxWidth)
                {
                    MaxWidth = _ucMethods.Width;
                }
            }

            //compare it to the Events expander controls width
            if (_ucEvents != null)
            {
                //is interface drawing area the widest renderable area
                if (_ucEvents.Width > MaxWidth)
                {
                    MaxWidth = _ucEvents.Width;
                }
            }
            #endregion

            //return the MaxWidth
            return MaxWidth + _MainBodyBorderWidth;
        }


        /// <summary>
        /// Paint the control, basically does a nice
        /// rounded corner rectangle with custom fill
        /// </summary>
        /// <param name="e">the event args</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            SolidBrush b_Black = new SolidBrush(Color.Black);
            SolidBrush b_White = new SolidBrush(Color.White);
            SolidBrush b_Border = new SolidBrush(_ClassBorderColor);

            #region Draw interface bubble
            //draw the interface bubble if required
            if (_Interfaces.Count > 0)
            {
                int ellipse_Y_Pos = _interfaces_Y_End_Pos + 5;
                g.FillEllipse(b_White, 10, ellipse_Y_Pos, 10, 10);
                Pen p = new Pen(b_Black);
                g.DrawEllipse(p, 10, ellipse_Y_Pos, 10, 10);
                g.DrawLine(p, new Point(15, _interfaceDrawingLineStart), 
                    new Point(15, _interfaceDrawingLineEnd));
            }
            #endregion

            #region Draw main class body
            //draw the main class body area
            g.SmoothingMode = SmoothingMode.AntiAlias;
            int borderOffset = (int)_MainBodyBorderWidth / 2;
            Rectangle rBounds = new Rectangle(0, _MainBodyRenderStart, this.Width - borderOffset,
                (this.Height - _MainBodyRenderStart) - borderOffset);
            const int diameter = 20;
            int radius = diameter / 2;
            // Create a GraphicsPath with curved top corners
            GraphicsPath path = this.GetRoundedRect(rBounds, radius);
            //draw background
            LinearGradientBrush linBrush = new LinearGradientBrush(
            rBounds, _ClassStartColor, _ClassEndColor, LinearGradientMode.Horizontal);
            g.FillPath(linBrush, path);
            //draw outline
            g.DrawPath(new Pen(b_Border, 2F), path);
            //draw the title string
            g.DrawString(this.Name, this.TitleFont, b_Black,
                new PointF(_genericSpaceSizeH*2, _interfaceDrawingLineEnd + _genericSpaceSizeV));




            if (!Program._isStandAloneApp)
            {
                //Is there a baseclass to render
                if (_type_to_Draw_Reflector.BaseType != null)
                {
                    //Dont include object inheritence rendering
                    if (! _type_to_Draw_Reflector.BaseType.Name.ToLower().Equals("object"))
                    {
                        DrawInheritenceArrow(g,path, _type_to_Draw_Reflector.BaseType.Name);
                        ////draw inheritence arrow
                        //Pen p = new Pen(b_Black);
                        //int arrowStartXPos = _genericSpaceSizeH * 2;
                        //int arrowStartYPos = _interfaceDrawingLineEnd + _genericSpaceSizeV + TitleFont.Height + 8;
                        //g.DrawLine(p, new Point(arrowStartXPos, arrowStartYPos),
                        //    new Point(arrowStartXPos + 5, arrowStartYPos));
                        //path = new GraphicsPath();
                        //path.AddLine(new Point(arrowStartXPos + 5, arrowStartYPos - 4),
                        //    new Point(arrowStartXPos + 5, arrowStartYPos + 4));
                        //path.AddLine(new Point(arrowStartXPos + 5, arrowStartYPos - 4),
                        //    new Point(arrowStartXPos + 9, arrowStartYPos));
                        //path.AddLine(new Point(arrowStartXPos + 9, arrowStartYPos),
                        //    new Point(arrowStartXPos + 5, arrowStartYPos + 4));
                        //g.FillPath(b_Black, path);
                        ////draw the base type name
                        //g.DrawString(_type_to_Draw_Reflector.BaseType.Name, _rowFont, b_Black,
                        //    new PointF(arrowStartXPos + 13, arrowStartYPos - _rowFont.Height / 2));
                    }
                       
                }
            }
            else 
            {
                //Is there a baseclass to render
                if (_type_to_Draw.BaseType != null)
                {
                    //Dont include object inheritence rendering
                    if (! _type_to_Draw.BaseType.Name.ToLower().Equals("object"))
                    {
                        DrawInheritenceArrow(g,path,_type_to_Draw.BaseType.Name);
                    }
                }
            }

            #endregion
        }


        private void DrawInheritenceArrow(Graphics g, GraphicsPath path, String baseName)
        {
            SolidBrush b_Black = new SolidBrush(Color.Black);
            SolidBrush b_White = new SolidBrush(Color.White);
            SolidBrush b_Border = new SolidBrush(_ClassBorderColor);

            //draw inheritence arrow
            Pen p = new Pen(b_Black);
            int arrowStartXPos = _genericSpaceSizeH * 2;
            int arrowStartYPos = _interfaceDrawingLineEnd + _genericSpaceSizeV + TitleFont.Height + 8;
            g.DrawLine(p, new Point(arrowStartXPos, arrowStartYPos),
                new Point(arrowStartXPos + 5, arrowStartYPos));
            path = new GraphicsPath();
            path.AddLine(new Point(arrowStartXPos + 5, arrowStartYPos - 4),
                new Point(arrowStartXPos + 5, arrowStartYPos + 4));
            path.AddLine(new Point(arrowStartXPos + 5, arrowStartYPos - 4),
                new Point(arrowStartXPos + 9, arrowStartYPos));
            path.AddLine(new Point(arrowStartXPos + 9, arrowStartYPos),
                new Point(arrowStartXPos + 5, arrowStartYPos + 4));
            g.FillPath(b_Black, path);
            //draw the base type name
            g.DrawString(baseName, _rowFont, b_Black,
                new PointF(arrowStartXPos + 13, arrowStartYPos - _rowFont.Height / 2));

        }



        /// <summary>
        /// Takes a rectangle, and returns a GraphicsPath which is a round cornered
        /// rectangle which is same size as base rectangle
        /// </summary>
        /// <param name="baseRect">the base rectangle (straight edged client area)</param>
        /// <param name="radius">a radius to use for corners</param>
        /// <returns>a GraphicsPath which is a round cornered rectangle which is same size
        /// as base rectangle</returns>
        private GraphicsPath GetRoundedRect(RectangleF baseRect,
           float radius)
        {
            // if corner radius is less than or equal to zero, 
            // return the original rectangle 
            if (radius <= 0.0F)
            {
                GraphicsPath mPath = new GraphicsPath();
                mPath.AddRectangle(baseRect);
                mPath.CloseFigure();
                return mPath;
            }
            // if the corner radius is greater than or equal to 
            // half the width, or height (whichever is shorter) 
            // then return a capsule instead of a lozenge 
            if (radius >= (Math.Min(baseRect.Width, baseRect.Height)) / 2.0)
                return GetCapsule(baseRect);
            // create the arc for the rectangle sides and declare 
            // a graphics path object for the drawing 
            float diameter = radius * 2.0F;
            SizeF sizeF = new SizeF(diameter, diameter);
            RectangleF arc = new RectangleF(baseRect.Location, sizeF);
            GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
            // top left arc 
            path.AddArc(arc, 180, 90);
            // top right arc 
            arc.X = baseRect.Right - diameter;
            path.AddArc(arc, 270, 90);
            // bottom right arc 
            arc.Y = baseRect.Bottom - diameter;
            path.AddArc(arc, 0, 90);
            // bottom left arc
            arc.X = baseRect.Left;
            path.AddArc(arc, 90, 90);
            path.CloseFigure();
            return path;
        }

        /// <summary>
        /// Takes a rectangle, and returns a GraphicsPath which is a round cornered
        /// rectangle which is same size as base rectangle
        /// </summary>
        /// <param name="baseRect">the base rectangle (straight edged client area)</param>
        /// <returns>a GraphicsPath which is a round cornered rectangle which is same size
        /// as base rectangle</returns>
        private GraphicsPath GetCapsule(RectangleF baseRect)
        {
            float diameter;
            RectangleF arc;
            GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
            try
            {
                if (baseRect.Width > baseRect.Height)
                {
                    // return horizontal capsule 
                    diameter = baseRect.Height;
                    SizeF sizeF = new SizeF(diameter, diameter);
                    arc = new RectangleF(baseRect.Location, sizeF);
                    path.AddArc(arc, 90, 180);
                    arc.X = baseRect.Right - diameter;
                    path.AddArc(arc, 270, 180);
                }
                else if (baseRect.Width < baseRect.Height)
                {
                    // return vertical capsule 
                    diameter = baseRect.Width;
                    SizeF sizeF = new SizeF(diameter, diameter);
                    arc = new RectangleF(baseRect.Location, sizeF);
                    path.AddArc(arc, 180, 180);
                    arc.Y = baseRect.Bottom - diameter;
                    path.AddArc(arc, 0, 180);
                }
                else
                {
                    // return circle 
                    path.AddEllipse(baseRect);
                }
            }
            catch (Exception)
            {
                path.AddEllipse(baseRect);
            }
            finally
            {
                path.CloseFigure();
            }
            return path;
        }

        /// <summary>
        /// Takes an input string and lower cases it and trims 
        /// it. Taking all chars after a "." (if one exists", 
        /// then returns it
        /// </summary>
        /// <param name="sIn">the input string</param>
        /// <returns>the input string lower cased and trimmed</returns>
        private string LowerAndTrim(string sIn)
        {
            string s = sIn;
            s = s.ToLower();
            if (s.IndexOf(".") > 0)
            {
                s = s.Substring(s.LastIndexOf(".") + 1);
            }
            return s;
        }


        /// <summary>
        /// Returs a string which is the name of the type in its full
        /// format. If its not a generic type, then the name of the
        /// t input parameter is simply returned, if however it is
        /// a generic method say a List of ints then the appropraite string
        /// will be retrurned
        /// </summary>
        /// <param name="t">The Type to check for generics</param>
        /// <returns></returns>
        private string getGenericsForTypeReflector(IType t)
        {
			return GetNameWithResolutionScope(t);
        }

		private static string GetNameWithResolutionScope(IType value)
		{
			ITypeReference typeReference = value as ITypeReference;
			if (typeReference != null)
			{
				return Helper.GetNameWithResolutionScope(typeReference);
			}

			IArrayType arrayType = value as IArrayType;
			if (arrayType != null)
			{
				return GetNameWithResolutionScope(arrayType.ElementType) + "[]";
			}

			IReferenceType referenceType = value as IReferenceType;
			if (referenceType != null)
			{
				return GetNameWithResolutionScope(referenceType.ElementType) + "&";
			}

			IPointerType pointerType = value as IPointerType;
			if (pointerType != null)
			{
				return GetNameWithResolutionScope(pointerType.ElementType) + "*";
			}

			throw new NotSupportedException();
		}

        /// <summary>
        /// Analyses the current Type (which was supplied on construction)
        /// and creates lists for its Constructors, Fields, Properties,
        /// Interfaces, Methods, Events to provide to these lists to
        /// <see cref="Expander">Expander </see>controls
        /// </summary>
        private void AnalyseTypeReflector()
        {

            // lists for containing get and set methods
			List<IMethodReference> propGetters = new List<IMethodReference>();
			List<IMethodReference> propSetters = new List<IMethodReference>();

            #region Fields
            //do fields
            foreach (IFieldDeclaration fi in _type_to_Draw_Reflector.Fields)
            {
                if (_type_to_Draw_Reflector.Equals(fi.DeclaringType))
                {
                    //add all the field types to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    string fName= getGenericsForTypeReflector(fi.FieldType);
                    fName = LowerAndTrim(fName);
                    if (!_Associations.Contains(fName))
                    {
                        _Associations.Add(fName);
                    }
                    //do we want long or short field description displayed
                    if (Program._IncludeFieldType)
                        _Fields.Add(fName + " " + fi.Name);
                    else
                        _Fields.Add(fi.Name);
                }
            }
            #endregion
            #region Properties
            //do properties
            foreach (IPropertyDeclaration pi in _type_to_Draw_Reflector.Properties)
            {
                if (_type_to_Draw_Reflector == pi.DeclaringType)
                {
                    // add read method if exists
					IMethodReference getMethod = pi.GetMethod as IMethodReference;
					if (getMethod != null)
					{
						propGetters.Add(getMethod);
					}

					// add write method if exists
					IMethodReference setMethod = pi.GetMethod as IMethodReference;
					if (setMethod != null)
					{
						propGetters.Add(setMethod);
					}

                    string pName=getGenericsForTypeReflector(pi.PropertyType);
                    //add all the property types to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    pName = LowerAndTrim(pName);
                    if (!_Associations.Contains(pName))
                    {
                        _Associations.Add(pName);
                    }


                    //do we want long or short property description displayed
                    if (Program._IncludePropValues)
                        _Properties.Add(pName + " " + pi.Name);
                    else
                        _Properties.Add(pi.Name);
                }
            }
            #endregion
            #region Interfaces
            //do interfaces
            if (Program._IncludeInterfaces)
            {
                ITypeReferenceCollection tiArray = _type_to_Draw_Reflector.Interfaces;
                foreach (ITypeReference ii in tiArray)
                {
                    _Interfaces.Add(ii.ToString());
                }
            }
            #endregion
            #region Methods
            //do methods
            foreach (IMethodDeclaration mi in _type_to_Draw_Reflector.Methods)
            { 
                if (_type_to_Draw_Reflector == mi.DeclaringType)
                {
                    string mDetail = mi.Name + "( ";
                    string pDetail="";
                    //do we want to display method arguments, if we do create the 
                    //appopraiate string
                    if (Program._IncludeMethodArgs)
                    {
                        IParameterDeclarationCollection pif = mi.Parameters;
                        foreach (IParameterDeclaration p in pif)
                        {
                            //add all the parameter types to the associations List, so that 
                            //the association lines for this class can be obtained, and 
                            //possibly drawn on the container
                            string pName=getGenericsForTypeReflector(p.ParameterType);
                            pName = LowerAndTrim(pName);
                            if (!_Associations.Contains(pName))
                            {
                                _Associations.Add(pName);
                            }
                            pDetail = pName + " " + p.Name + ", ";
                            mDetail += pDetail;
                        }
                        if (mDetail.LastIndexOf(",") > 0)
                        {
                            mDetail = mDetail.Substring(0, mDetail.LastIndexOf(","));
                        }
                    }
                    mDetail += " )";
                    //add the return type to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    string rName=getGenericsForTypeReflector(mi.ReturnType.Type);
                    //dont want to include void as an association type
                    if (!string.IsNullOrEmpty(rName))
                    {
                        rName=getGenericsForTypeReflector(mi.ReturnType.Type);
                        rName = LowerAndTrim(rName);
                        if (!_Associations.Contains(rName))
                        {
                            _Associations.Add(rName);
                        }
                        //do we want to display method return types
                        if (Program._IncludeMethodReturnType)
                            mDetail += " : " + rName;
                    }
                    else 
                    {
                        //do we want to display method return types
                        if (Program._IncludeMethodReturnType)
                            mDetail += " : void";
                    }
                    //work out whether this is a normal method, in which case add it
                    //or if its a property get/set method, should it be added
                    if (!Program._ShowPropGetters && propGetters.Contains(mi)) { /* hidden get method */ }
                    else if (!Program._ShowPropSetters && propSetters.Contains(mi)) { /* hidden set method */ }
                    else {
                                        _Methods.Add(mDetail);
                    }
                }
            }
            #endregion
            #region Events
            //do events
            foreach (IEventDeclaration ei in _type_to_Draw_Reflector.Events)
            {
                if (_type_to_Draw_Reflector.Equals(ei.DeclaringType))
                {
                    //add all the event types to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    string eName=getGenericsForTypeReflector(ei.EventType);
                    eName = LowerAndTrim(eName);
                    if (!_Associations.Contains(eName))
                    {
                        _Associations.Add(eName);
                    }

                    //do we want long or short event description displayed
                    if (Program._IncludeEventType)
                        _Events.Add(eName + " " + ei.Name);
                    else
                        _Events.Add(ei.Name);
                }
            }
            #endregion
        }


        /// <summary>
        /// Returs a string which is the name of the type in its full
        /// format. If its not a generic type, then the name of the
        /// t input parameter is simply returned, if however it is
        /// a generic method say a List of ints then the appropraite string
        /// will be retrurned
        /// </summary>
        /// <param name="t">The Type to check for generics</param>
        /// <returns></returns>
        private string getGenericsForType(Type t)
        {
            string name ="";
            if (!t.GetType().IsGenericType)
            {
                //see if there is a ' char, which there is for
                //generic types
                int idx  = t.Name.IndexOfAny(new char[] {'`','\''});
                if (idx >= 0)
                {
                    name=t.Name.Substring(0,idx);
                    //get the generic arguments
                    Type[] genTypes =t.GetGenericArguments();
                    //and build the list of types for the result string
                    if (genTypes.Length == 1) 
                    {
                        //name+="<" + genTypes[0].Name + ">";
                        name+="<" + getGenericsForType(genTypes[0]) + ">";
                    }
                    else 
                    {
                        name+="<";
                        foreach(Type gt in genTypes)
                        {
                            name+= getGenericsForType(gt) + ", ";
                        }
                        if (name.LastIndexOf(",") > 0)
                        {
                            name = name.Substring(0, name.LastIndexOf(","));
                        }
                        name+=">";
                    }
                }
                else 
                {
                    name=t.Name;
                }
                return name;
            }
            else 
            {
                return t.Name;
            }
        }


        /// <summary>
        /// Analyses the current Type (which was supplied on construction)
        /// and creates lists for its Constructors, Fields, Properties,
        /// Interfaces, Methods, Events to provide to these lists to
        /// <see cref="ucExpander">ucExpander </see>controls
        /// </summary>
        private void AnalyseType()
        {

            // lists for containing get and set methods
            List<MethodInfo> propGetters = new List<MethodInfo>();
            List<MethodInfo> propSetters = new List<MethodInfo>();


            #region Constructors
            //do constructors
            foreach (ConstructorInfo ci in _type_to_Draw.GetConstructors(Program.RequiredBindings))
            {
                if (_type_to_Draw == ci.DeclaringType)
                {

                    string cDetail = _type_to_Draw.Name + "( ";
                    string pDetail="";

                    //add all the constructor param types to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    ParameterInfo[] pif = ci.GetParameters();
                    foreach (ParameterInfo p in pif)
                    {
                        string pName=getGenericsForType(p.ParameterType);
                        pName = LowerAndTrim(pName);
                        if (!_Associations.Contains(pName))
                        {
                            _Associations.Add(pName);
                        }
                        pDetail = pName + " " + p.Name + ", ";
                        cDetail += pDetail;
                    }
                    if (cDetail.LastIndexOf(",") > 0)
                    {
                        cDetail = cDetail.Substring(0, cDetail.LastIndexOf(","));
                    }
                    cDetail += ")";
                    //do we want long or short field constructor displayed
                    if (Program._FullConstructorDescribe)
                    {
                        
                        //_Constructors.Add(ci.ToString().Replace(".ctor", ""));
                        _Constructors.Add(cDetail);
                    }
                    else
                        _Constructors.Add(_type_to_Draw.Name + "( )");
                }
            }
            #endregion
            #region Fields
            //do fields
            foreach (FieldInfo fi in _type_to_Draw.GetFields(Program.RequiredBindings))
            {
                if (_type_to_Draw == fi.DeclaringType)
                {
                    //add all the field types to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    string fName=getGenericsForType(fi.FieldType);
                    fName = LowerAndTrim(fName);
                    if (!_Associations.Contains(fName))
                    {
                        _Associations.Add(fName);
                    }
                    //do we want long or short field description displayed
                    if (Program._IncludeFieldType)
                        _Fields.Add(fName + " " + fi.Name);
                    else
                        _Fields.Add(fi.Name);
                }
            }
            #endregion
            #region Properties
            //do properties
            foreach (PropertyInfo pi in _type_to_Draw.GetProperties(Program.RequiredBindings))
            {
                if (_type_to_Draw == pi.DeclaringType)
                {
                    // add read method if exists
                    if (pi.CanRead) { propGetters.Add(pi.GetGetMethod(true)); }
                    // add write method if exists
                    if (pi.CanWrite) { propSetters.Add(pi.GetSetMethod(true)); }

                    string pName=getGenericsForType(pi.PropertyType);
                    //add all the property types to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    pName = LowerAndTrim(pName);
                    if (!_Associations.Contains(pName))
                    {
                        _Associations.Add(pName);
                    }


                    //do we want long or short property description displayed
                    if (Program._IncludePropValues)
                        _Properties.Add(pName + " " + pi.Name);
                    else
                        _Properties.Add(pi.Name);
                }
            }
            #endregion
            #region Interfaces
            //do interfaces
            if (Program._IncludeInterfaces)
            {
                Type[] tiArray = _type_to_Draw.GetInterfaces();
                foreach (Type ii in tiArray)
                {
                    _Interfaces.Add(ii.Name.ToString());
                }
            }
            #endregion
            #region Methods
            //do methods
            foreach (MethodInfo mi in _type_to_Draw.GetMethods(Program.RequiredBindings))
            { 
                if (_type_to_Draw == mi.DeclaringType)
                {
                    string mDetail = mi.Name + "( ";
                    string pDetail="";
                    //do we want to display method arguments, if we do create the 
                    //appopraiate string
                    if (Program._IncludeMethodArgs)
                    {
                        ParameterInfo[] pif = mi.GetParameters();
                        foreach (ParameterInfo p in pif)
                        {
                            //add all the parameter types to the associations List, so that 
                            //the association lines for this class can be obtained, and 
                            //possibly drawn on the container
                            string pName=getGenericsForType(p.ParameterType);
                            pName = LowerAndTrim(pName);
                            if (!_Associations.Contains(pName))
                            {
                                _Associations.Add(pName);
                            }
                            pDetail = pName + " " + p.Name + ", ";
                            mDetail += pDetail;
                        }
                        if (mDetail.LastIndexOf(",") > 0)
                        {
                            mDetail = mDetail.Substring(0, mDetail.LastIndexOf(","));
                        }
                    }
                    mDetail += " )";
                    //add the return type to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    string rName=getGenericsForType(mi.ReturnType);
                    //dont want to include void as an association type
                    if (!string.IsNullOrEmpty(rName))
                    {
                        rName=getGenericsForType(mi.ReturnType);
                        rName = LowerAndTrim(rName);
                        if (!_Associations.Contains(rName))
                        {
                            _Associations.Add(rName);
                        }
                        //do we want to display method return types
                        if (Program._IncludeMethodReturnType)
                            mDetail += " : " + rName;
                    }
                    else 
                    {
                        //do we want to display method return types
                        if (Program._IncludeMethodReturnType)
                            mDetail += " : void";
                    }
                    //work out whether this is a normal method, in which case add it
                    //or if its a property get/set method, should it be added
                    if (!Program._ShowPropGetters && propGetters.Contains(mi)) { /* hidden get method */ }
                    else if (!Program._ShowPropSetters && propSetters.Contains(mi)) { /* hidden set method */ }
                    else {
                                        _Methods.Add(mDetail);
                    }
                }
            }
            #endregion
            #region Events
            //do events
            foreach (EventInfo ei in _type_to_Draw.GetEvents(Program.RequiredBindings))
            {
                if (_type_to_Draw == ei.DeclaringType)
                {
                    //add all the event types to the associations List, so that 
                    //the association lines for this class can be obtained, and 
                    //possibly drawn on the container
                    string eName=getGenericsForType(ei.EventHandlerType);
                    eName = LowerAndTrim(eName);
                    if (!_Associations.Contains(eName))
                    {
                        _Associations.Add(eName);

                    }

                    //do we want long or short event description displayed
                    if (Program._IncludeEventType)
                        _Events.Add(eName + " " + ei.Name);
                    else
                        _Events.Add(ei.Name);
                }
            }
            #endregion
        }

        /// <summary>
        /// Constructs a tooltip for this classes known associations
        /// </summary>
        /// <param name="sender">DrawableClass</param>
        /// <param name="e">the event args</param>
        private void DrawableClass_MouseHover(object sender, EventArgs e)
        {
            if (_Associations.Count > 0)
            {
                string assClasses="ASSOCIATIONS\r\n\r\n";

                foreach(string s in _Associations)
                {
                    assClasses+=s +"\r\n";
                }
                toolTip1.Show(assClasses,this,5000);
            }
        }


        #endregion


    }
    #endregion
    #region SizeEventArgs CLASS
    /// <summary>
    /// provides the events args for the <see cref="DrawableClass">
    /// DrawableClass </see>SizeChanged event
    /// </summary>
    public class SizeEventArgs : System.EventArgs
    {
        #region Instance Fields
        //instance fields
        private DrawableClass ucd;
        #endregion
        #region Ctor
        /// <summary>
        /// Constructs a new SizeEventArgs using the params provided
        /// </summary>
        /// <param name="ucd">A <see cref="DrawableClass">DrawableClass </see>
        /// DrawableClass</param>object which raised the event
        public SizeEventArgs(DrawableClass ucd)
        {
            this.ucd = ucd;
        }
        #endregion
        #region Public Properties
        /// <summary>
        /// gets the CurrentState collapsed / expanded
        /// </summary>
        public DrawableClass.States CurrentState
        {
            get { return this.ucd.CurrentState; }
        }
        #endregion
    }
    #endregion

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions