Click here to Skip to main content
15,885,164 members
Articles / Programming Languages / C#

A Simple Wizard Control for .Net 2.0 with Full Designer Support

Rate me:
Please Sign up or sign in to vote.
4.65/5 (131 votes)
4 Feb 2008CPOL4 min read 524.9K   13.9K   382  
This is a simple yet powerful wizard framework for .Net 2.0. Just drag and drop and your component is ready for use.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;

namespace WizardBase
{
    public class GenericCollection<T> : CollectionBase, IDeserializationCallback, IDisposable, ISerializable
    {
        #region Delegates

        public delegate void CollectionChangedHandler(int index, T value);

        public delegate void CollectionChangingHandler(int index, GenericCancelEventArgs<T> value);

        public delegate void CollectionClearHandler();

        public delegate void CollectionClearingHandler(GenericCancelEventArgs<GenericCollection<T>> value);

        public delegate void ItemChangeHandler(int index, T oldValue, T newValue);

        public delegate void ItemChangingHandler(int index, GenericChangeEventArgs<T> e);

        public delegate void ValidateHandle(T value);

        #endregion

        #region Constructor

        public GenericCollection()
        {
        }

        public GenericCollection(object owner)
        {
            this.owner = owner;
        }

        protected GenericCollection(SerializationInfo info, StreamingContext context)
        {
            siInfo = info;
        }

        public GenericCollection(IEnumerable<T> items)
            : this()
        {
            foreach (T barItem in items)
            {
#pragma warning disable DoNotCallOverridableMethodsInConstructor
                OnInsert(InnerList.Count, barItem);
#pragma warning restore DoNotCallOverridableMethodsInConstructor
                InnerList.Add(barItem);
#pragma warning disable DoNotCallOverridableMethodsInConstructor
                OnInsertComplete(InnerList.Count - 1, barItem);
#pragma warning restore DoNotCallOverridableMethodsInConstructor
            }
        }

        public GenericCollection(GenericCollection<T> items)
            : this()
        {
            foreach (T item in items)
            {
                T newItem = (T)(item is ICloneable ? (item as ICloneable).Clone() : item);
#pragma warning disable DoNotCallOverridableMethodsInConstructor
                OnInsert(InnerList.Count, newItem);
#pragma warning restore DoNotCallOverridableMethodsInConstructor
                InnerList.Add(newItem);
#pragma warning disable DoNotCallOverridableMethodsInConstructor
                OnInsertComplete(InnerList.Count - 1, newItem);
#pragma warning restore DoNotCallOverridableMethodsInConstructor
            }
        }

        #endregion

        #region Property

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public T this[int index]
        {
            get { return (T)InnerList[index]; }
            set { InnerList[index] = value; }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public object Owner
        {
            get { return owner; }
            set { owner = value; }
        }

        #endregion

        #region Events

        public event CollectionClearHandler Cleared;

        public event CollectionClearingHandler Clearing;

        public event CollectionChangedHandler Inserted;

        public event CollectionChangingHandler Inserting;

        public event CollectionChangedHandler Removed;

        public event CollectionChangingHandler Removing;

        public event ItemChangingHandler Changing;

        public event ItemChangeHandler Changed;

        public event ValidateHandle Validating;

        #endregion

        #region Public Methods

        /// <summary>
        /// Adds an item to the end of the collection.
        /// </summary>
        /// <param name="item">The item to be added to the end of the Collection. The value can be null.</param>
        /// <returns>The index at which the value has been added.</returns>
        public int Add(T item)
        {
            OnInsert(InnerList.Count, item);
            int index = InnerList.Add(item);
            OnInsertComplete(InnerList.Count, item);
            return index;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="items"></param>
        public void AddRange(T[] items)
        {
            foreach (T item in items)
            {
                OnInsert(InnerList.Count, item);
                InnerList.Add(item);
                OnInsertComplete(InnerList.Count, item);
            }
        }

        /// <summary>
        /// Adds an item(s) to the end of the collection.
        /// </summary>
        /// <param name="items">The item to be added to the end of the Collection. The value can be null. </param>
        public void Add(T[] items)
        {
            foreach (T item in items)
            {
                OnInsert(InnerList.Count, item);
                InnerList.Add(item);
                OnInsertComplete(InnerList.Count, item);
            }
        }

        /// <summary>
        /// Inserts an element into the Collection at the specified index.
        /// </summary>
        /// <param name="index">Index at which item has to be inserted.</param>
        /// <param name="item">Item to be inserted</param>
        public void Insert(int index, T item)
        {
            OnInsert(index, item);
            InnerList.Insert(index, item);
            OnInsertComplete(index, item);
        }

        /// <summary>
        /// Removes item from the collection.
        /// </summary>
        /// <param name="item">Item to be removed.</param>
        public void Remove(T item)
        {
            int index = IndexOf(item);
            OnRemove(index, item);
            InnerList.Remove(item);
            OnRemoveComplete(index, item);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public int LastIndexOf(T item)
        {
            return InnerList.LastIndexOf(item);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public int LastIndexOf(T item, int startIndex)
        {
            return InnerList.LastIndexOf(item, startIndex);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int LastIndexOf(T item, int startIndex, int count)
        {
            return InnerList.LastIndexOf(item, startIndex, count);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="index"></param>
        /// <param name="items"></param>
        public void InsertRange(int index, GenericCollection<T> items)
        {
            InnerList.InsertRange(index, items);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Contains(T item)
        {
            return InnerList.Contains(item);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public int IndexOf(T value)
        {
            return InnerList.IndexOf(value);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public int IndexOf(T value, int startIndex)
        {
            return InnerList.IndexOf(value, startIndex);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="startIndex"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int IndexOf(T value, int startIndex, int count)
        {
            return InnerList.IndexOf(value, startIndex, count);
        }

        #endregion

        #region Overrides

        ///<summary>
        ///Performs additional custom processes when clearing the contents of the <see cref="T:System.Collections.CollectionBase"></see> instance.
        ///</summary>
        ///
        protected override void OnClear()
        {
            GenericCancelEventArgs<GenericCollection<T>> e = new GenericCancelEventArgs<GenericCollection<T>>(this);
            if (Clearing != null)
            {
                Clearing(e);
                if (e.Cancel)
                {
                    return;
                }
            }
            base.OnClear();
        }

        ///<summary>
        ///Performs additional custom processes after clearing the contents of the <see cref="T:System.Collections.CollectionBase"></see> instance.
        ///</summary>
        ///
        protected override void OnClearComplete()
        {
            base.OnClearComplete();
            if (Cleared != null)
            {
                Cleared();
            }
        }

        ///<summary>
        ///Performs additional custom processes before inserting a new element into the <see cref="T:System.Collections.CollectionBase"></see> instance.
        ///</summary>
        ///
        ///<param name="value">The new value of the element at index.</param>
        ///<param name="index">The zero-based index at which to insert value.</param>
        protected override void OnInsert(int index, object value)
        {
            GenericCancelEventArgs<T> e = new GenericCancelEventArgs<T>((T)value);
            if (Inserting != null)
            {
                Inserting(index, e);
                if (e.Cancel)
                {
                    return;
                }
            }
            base.OnInsert(index, value);
        }

        ///<summary>
        ///Performs additional custom processes after inserting a new element into the <see cref="T:System.Collections.CollectionBase"></see> instance.
        ///</summary>
        ///
        ///<param name="value">The new value of the element at index.</param>
        ///<param name="index">The zero-based index at which to insert value.</param>
        protected override void OnInsertComplete(int index, object value)
        {
            base.OnInsertComplete(index, value);
            if (Inserted != null)
            {
                Inserted(index, (T)value);
            }
        }

        ///<summary>
        ///Performs additional custom processes when removing an element from the <see cref="T:System.Collections.CollectionBase"></see> instance.
        ///</summary>
        ///
        ///<param name="value">The value of the element to remove from index.</param>
        ///<param name="index">The zero-based index at which value can be found.</param>
        protected override void OnRemove(int index, object value)
        {
            GenericCancelEventArgs<T> e = new GenericCancelEventArgs<T>((T)value);
            if (Removing != null)
            {
                Removing(index, e);
                if (e.Cancel)
                {
                    return;
                }
            }
            base.OnRemove(index, value);
        }

        ///<summary>
        ///Performs additional custom processes after removing an element from the <see cref="T:System.Collections.CollectionBase"></see> instance.
        ///</summary>
        ///
        ///<param name="value">The value of the element to remove from index.</param>
        ///<param name="index">The zero-based index at which value can be found.</param>
        protected override void OnRemoveComplete(int index, object value)
        {
            base.OnRemoveComplete(index, value);
            if (Removed != null)
            {
                Removed(index, (T)value);
            }
        }

        ///<summary>
        ///Performs additional custom processes when validating a value.
        ///</summary>
        ///
        ///<param name="value">The object to validate.</param>
        protected override void OnValidate(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException();
            }
            if (Validating != null)
            {
                Validating((T)value);
            }
            base.OnValidate(value);
        }

        ///<summary>
        ///Performs additional custom processes before setting a value in the <see cref="T:System.Collections.CollectionBase"></see> instance.
        ///</summary>
        ///
        ///<param name="oldValue">The value to replace with newValue.</param>
        ///<param name="newValue">The new value of the element at index.</param>
        ///<param name="index">The zero-based index at which oldValue can be found.</param>
        protected override void OnSet(int index, object oldValue, object newValue)
        {
            GenericChangeEventArgs<T> e = new GenericChangeEventArgs<T>((T)oldValue, (T)newValue);
            if (Changing != null)
            {
                Changing(index, e);
                if (e.Cancel)
                {
                    return;
                }
            }
            base.OnSet(index, oldValue, newValue);
        }

        ///<summary>
        ///Performs additional custom processes after setting a value in the <see cref="T:System.Collections.CollectionBase"></see> instance.
        ///</summary>
        ///
        ///<param name="oldValue">The value to replace with newValue.</param>
        ///<param name="newValue">The new value of the element at index.</param>
        ///<param name="index">The zero-based index at which oldValue can be found.</param>
        protected override void OnSetComplete(int index, object oldValue, object newValue)
        {
            base.OnSetComplete(index, oldValue, newValue);
            if (Changed != null)
            {
                Changed(index, (T)oldValue, (T)newValue);
            }
        }

        #endregion

        private object owner;

        private SerializationInfo siInfo;

        #region IDeserializationCallback Members

        ///<summary>
        ///Runs when the entire object graph has been deserialized.
        ///</summary>
        ///
        ///<param name="sender">The object that initiated the callback. The functionality for this parameter is not currently implemented. </param>
        public void OnDeserialization(object sender)
        {
            if (siInfo != null)
            {
                Clear();
                if (siInfo.GetInt32("Count") != 0)
                {
                    Clear();
                    int num = siInfo.GetInt32("Count");
                    for (int i = 0; i < num; i++)
                    {
                        Add((T)siInfo.GetValue("Items" + i, typeof(T)));
                    }
                }
                siInfo = null;
            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            owner = null;
            List.Clear();
            InnerList.Clear();
            siInfo = null;
        }

        #endregion

        #region ISerializable Members

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }
            info.AddValue("Count", Count);
            if (Count != 0)
            {
                for (int i = 0; i < Count; i++)
                {
                    info.AddValue("Items" + i, this[i]);
                }
            }
        }

        #endregion

        public void SetChildIndex(T item, int index)
        {
            if (List.Count > 0)
            {
                int num = IndexOf(item);
                if (index < 0)
                {
                    index = 0;
                }
                if (index >= List.Count)
                {
                    index = List.Count - 1;
                }
                if ((index >= 0) && (index < List.Count))
                {
                    if (num < index)
                    {
                        for (int i = num; i < index; i++)
                        {
                            List[i] = List[i + 1];
                        }
                        List[index] = item;
                    }
                    else if (num > index)
                    {
                        for (int j = num; j > index; j--)
                        {
                            List[j] = List[j - 1];
                        }
                        List[index] = item;
                    }
                }
            }
        }

        public void Sort(IComparer comparer)
        {
            if ((List.Count > 0) && (comparer != null))
            {
                object[] array = new object[List.Count];
                for (int i = 0; i < List.Count; i++)
                {
                    array[i] = List[i];
                }
                Array.Sort(array, comparer);
                List.Clear();
                for (int j = 0; j < array.Length; j++)
                {
                    List.Add(array[j]);
                }
            }
        }
    }
}

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)
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions