Click here to Skip to main content
15,886,110 members
Articles / Programming Languages / C#

CIMTool for Windows Management Instrumentation - Part 1

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
22 Feb 2013CPOL6 min read 37.2K   7.6K   31  
Use WMI to retrieve information about your system and genrate classes for easy WMI development.
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Management;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Security.Permissions;
using System.Security;

namespace Harlinn.CIMTool.Types
{
    [Serializable]
    public class BindingListEx<T> : BaseElement, ITypedList ,ICustomTypeDescriptor, IList<T>, IList, IBindingList, ICancelAddNew, IRaiseItemChangedEvents where T : BaseElement
    {
        private static void LogException(Exception exc, MethodBase method)
        {
 
        }


        IList<T> items;
        [NonSerialized]
        private Object synchRoot;

        [NonSerialized()]
        private static ReflectionPermission memberAccessPermission = null;

        [NonSerialized()]
        private static ReflectionPermission restrictedMemberAccessPermission = null;

        private int addNewPos = -1;
        private bool raiseListChangedEvents = true;
        private bool raiseItemChangedEvents = false;

        [NonSerialized()]
        private PropertyDescriptorCollection itemTypeProperties = null;

        [NonSerialized()]
        private PropertyChangedEventHandler propertyChangedEventHandler = null;

        [NonSerialized()]
        private AddingNewEventHandler onAddingNew;

        [NonSerialized()]
        private ListChangedEventHandler onListChanged;

        [NonSerialized()]
        private int lastChangeIndex = -1;

        private bool allowNew = true;
        private bool allowEdit = true;
        private bool allowRemove = true;
        private bool userSetAllowNew = false;


        public BindingListEx()
        {
            try
            {
                items = new List<T>();
                Initialize();
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public BindingListEx(IList<T> list)
        {
            try
            {
                if (list == null)
                {
                    throw new ArgumentNullException("list");
                }
                items = list;
                Initialize();
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        public int Compare(IList<T> list)
        {
            int result = Count - list.Count;
            if (result == 0)
            {
                for (int i = 0; i < Count; i++)
                {
                    T first = items[i];
                    T second = list[i];
                    int compareResult = first.Compare(second);
                    if (compareResult != 0)
                    {
                        result = compareResult;
                    }

                }
            }
            return result;
        }


        [Browsable(false)]
        public int Count
        {
            get
            {
                try
                {
                    return items.Count;
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }


        protected IList<T> Items
        {
            get
            {
                return items;
            }
        }


        public T this[int index]
        {
            get
            {
                return items[index];
            }
            set
            {
                try
                {
                    if (items.IsReadOnly)
                    {
                        throw new NotSupportedException("This is a read only collection, operation not supported.");
                    }

                    if (index < 0 || index >= items.Count)
                    {
                        throw new ArgumentOutOfRangeException(string.Format("Index ({1}) out of range, number of elements in the collection is {0}.", Count, index));
                    }

                    SetItem(index, value);
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        public void Add(T item)
        {
            try
            {
                if (items.IsReadOnly)
                {
                    throw new NotSupportedException("This is a read only collection, operation not supported.");
                }

                int index = items.Count;
                InsertItem(index, item);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public void Clear()
        {
            try
            {
                if (items.IsReadOnly)
                {
                    throw new NotSupportedException("This is a read only collection, operation not supported.");
                }

                ClearItems();
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        public void CopyTo(T[] array, int index)
        {
            try
            {
                items.CopyTo(array, index);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        public bool Contains(T item)
        {
            try
            {
                return items.Contains(item);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public IEnumerator<T> GetEnumerator()
        {
            try
            {
                return items.GetEnumerator();
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public int IndexOf(T item)
        {
            try
            {
                return items.IndexOf(item);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        public void Insert(int index, T item)
        {
            try
            {
                if (items.IsReadOnly)
                {
                    throw new NotSupportedException("This is a read only collection, operation not supported.");
                }

                if (index < 0 || index > items.Count)
                {
                    throw new ArgumentOutOfRangeException(string.Format("Index ({1}) out of range, number of elements in the collection is {0}.", Count, index));
                }

                InsertItem(index, item);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public bool Remove(T item)
        {
            try
            {
                if (items.IsReadOnly)
                {
                    throw new NotSupportedException("This is a read only collection, operation not supported.");
                }

                int index = items.IndexOf(item);
                if (index < 0) return false;
                RemoveItem(index);
                return true;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public void RemoveAt(int index)
        {
            try
            {
                if (items.IsReadOnly)
                {
                    throw new NotSupportedException("This is a read only collection, operation not supported.");
                }

                if (index < 0 || index >= items.Count)
                {
                    throw new ArgumentOutOfRangeException(string.Format("Index ({1}) out of range, number of elements in the collection is {0}.", Count, index));
                }

                RemoveItem(index);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        [Browsable(false)]
        bool ICollection<T>.IsReadOnly
        {
            get
            {
                try
                {
                    return items.IsReadOnly;
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            try
            {
                return ((IEnumerable)items).GetEnumerator();
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        bool ICollection.IsSynchronized
        {
            get
            {
                return false;
            }
        }

        [Browsable(false)]
        object ICollection.SyncRoot
        {
            get
            {
                try
                {
                    if (synchRoot == null)
                    {
                        ICollection c = items as ICollection;
                        if (c != null)
                        {
                            synchRoot = c.SyncRoot;
                        }
                        else
                        {
                            System.Threading.Interlocked.CompareExchange<Object>(ref synchRoot, new Object(), null);
                        }
                    }
                    return synchRoot;
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        void ICollection.CopyTo(Array array, int index)
        {
            try
            {
                if (array == null)
                {
                    throw new ArgumentNullException("array");
                }

                if (array.Rank != 1)
                {
                    throw new ArgumentException("Multi dimensional arrays not supported.");
                }

                if (array.GetLowerBound(0) != 0)
                {
                    throw new ArgumentException("Arrays with non-zero lower bound not supported.");
                }

                if (index < 0)
                {
                    throw new ArgumentOutOfRangeException(string.Format("Index ({1}) out of range, number of elements in the collection is {0}.", Count, index));
                }

                if (array.Length - index < Count)
                {
                    throw new ArgumentException("Length of array too small.");
                }

                T[] tArray = array as T[];
                if (tArray != null)
                {
                    items.CopyTo(tArray, index);
                }
                else
                {
                    Type targetType = array.GetType().GetElementType();
                    Type sourceType = typeof(T);
                    if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
                    {
                        throw new ArgumentException("Invalid array type.");
                    }

                    object[] objects = array as object[];
                    if (objects == null)
                    {
                        // T is not an object
                        throw new ArgumentException("Invalid array type.");
                    }

                    int count = items.Count;
                    try
                    {
                        for (int i = 0; i < count; i++)
                        {
                            objects[index++] = items[i];
                        }
                    }
                    catch (ArrayTypeMismatchException)
                    {
                        throw new ArgumentException("Invalid array type.");
                    }
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        [Browsable(false)]
        object IList.this[int index]
        {
            get
            {
                return items[index];
            }
            set
            {
                try
                {
                    if (value == null)
                    {
                        throw new ArgumentNullException("value");
                    }

                    try
                    {
                        this[index] = (T)value;
                    }
                    catch (InvalidCastException)
                    {
                        throw new ArgumentException("Invalid type");
                    }
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }

            }
        }

        [Browsable(false)]
        bool IList.IsReadOnly
        {
            get
            {
                try
                {
                    return items.IsReadOnly;
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        [Browsable(false)]
        bool IList.IsFixedSize
        {
            get
            {
                try
                {
                    IList list = items as IList;
                    if (list != null)
                    {
                        return list.IsFixedSize;
                    }
                    return items.IsReadOnly;
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        int IList.Add(object value)
        {
            try
            {
                if (items.IsReadOnly)
                {
                    throw new NotSupportedException("This is a read only collection, operation not supported.");
                }
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }

                try
                {
                    Add((T)value);
                }
                catch (InvalidCastException)
                {
                    throw new ArgumentException("Invalid type");
                }

                return this.Count - 1;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        bool IList.Contains(object value)
        {
            try
            {
                if (IsCompatibleObject(value))
                {
                    return Contains((T)value);
                }
                return false;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        int IList.IndexOf(object value)
        {
            try
            {
                if (IsCompatibleObject(value))
                {
                    return IndexOf((T)value);
                }
                return -1;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        void IList.Insert(int index, object value)
        {
            try
            {
                if (items.IsReadOnly)
                {
                    throw new NotSupportedException("This is a read only collection, operation not supported.");
                }
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }

                try
                {
                    Insert(index, (T)value);
                }
                catch (InvalidCastException)
                {
                    throw new ArgumentException("Invalid type");
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }

        }

        void IList.Remove(object value)
        {
            try
            {
                if (items.IsReadOnly)
                {
                    throw new NotSupportedException("This is a read only collection, operation not supported.");
                }

                if (IsCompatibleObject(value))
                {
                    Remove((T)value);
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        private static bool IsCompatibleObject(object value)
        {
            try
            {
                return ((value is T) || (value == null && default(T) == null));
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public AttributeCollection GetAttributes()
        {
            try
            {
                return TypeDescriptor.GetAttributes(this, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public string GetClassName()
        {
            try
            {
                return TypeDescriptor.GetClassName(this, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public string GetComponentName()
        {
            try
            {
                return TypeDescriptor.GetComponentName(this, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public TypeConverter GetConverter()
        {
            try
            {
                return TypeDescriptor.GetConverter(this, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public EventDescriptor GetDefaultEvent()
        {
            try
            {
                return TypeDescriptor.GetDefaultEvent(this, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public PropertyDescriptor GetDefaultProperty()
        {
            try
            {
                return TypeDescriptor.GetDefaultProperty(this, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public object GetEditor(Type editorBaseType)
        {
            try
            {
                return TypeDescriptor.GetEditor(this, editorBaseType, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            try
            {
                return TypeDescriptor.GetEvents(this, attributes, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public EventDescriptorCollection GetEvents()
        {
            try
            {
                return TypeDescriptor.GetEvents(this, true);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            try
            {
                return GetProperties();
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        protected virtual PropertyDescriptor GetPropertyDescriptor(int index)
        {
            try
            {
                CollectionPropertyDescriptor<T> result = new CollectionPropertyDescriptor<T>(this, index);
                return result;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        public virtual PropertyDescriptorCollection GetProperties()
        {
            try
            {
                PropertyDescriptorCollection result = new PropertyDescriptorCollection(null);

                for (int i = 0; i < items.Count; i++)
                {
                    PropertyDescriptor propertyDescriptor = GetPropertyDescriptor(i);
                    result.Add(propertyDescriptor);
                }

                return result;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            try
            {
                return this;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        private void Initialize()
        {
            try
            {
                this.allowNew = ItemTypeHasDefaultConstructor;

                if (typeof(INotifyPropertyChanged).IsAssignableFrom(typeof(T)))
                {
                    this.raiseItemChangedEvents = true;

                    foreach (T item in this.Items)
                    {
                        HookPropertyChanged(item);
                    }
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        [Browsable(false)]
        private bool ItemTypeHasDefaultConstructor
        {
            get
            {
                try
                {
                    Type itemType = typeof(T);

                    if (itemType.IsPrimitive)
                    {
                        return true;
                    }

                    if (itemType.GetConstructor(BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, null, new Type[0], null) != null)
                    {
                        return true;
                    }

                    return false;
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        public event AddingNewEventHandler AddingNew
        {
            add
            {
                try
                {
                    bool allowNewWasTrue = AllowNew;
                    onAddingNew += value;
                    if (allowNewWasTrue != AllowNew)
                    {
                        FireListChanged(ListChangedType.Reset, -1);
                    }
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
            remove
            {
                try
                {
                    bool allowNewWasTrue = AllowNew;
                    onAddingNew -= value;
                    if (allowNewWasTrue != AllowNew)
                    {
                        FireListChanged(ListChangedType.Reset, -1);
                    }
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        protected virtual void OnAddingNew(AddingNewEventArgs e)
        {
            try
            {
                if (onAddingNew != null)
                {
                    onAddingNew(this, e);
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        protected object FireAddingNew()
        {
            try
            {
                AddingNewEventArgs e = new AddingNewEventArgs(null);
                OnAddingNew(e);
                return e.NewObject;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }



        public event ListChangedEventHandler ListChanged
        {
            add
            {
                onListChanged += value;
            }
            remove
            {
                onListChanged -= value;
            }
        }

        protected virtual void OnListChanged(ListChangedEventArgs e)
        {
            try
            {
                if (onListChanged != null)
                {
                    onListChanged(this, e);
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        [Browsable(false)]
        public bool RaiseListChangedEvents
        {
            get
            {
                return this.raiseListChangedEvents;
            }

            set
            {
                if (this.raiseListChangedEvents != value)
                {
                    this.raiseListChangedEvents = value;
                }
            }
        }

        public void ResetBindings()
        {
            try
            {
                FireListChanged(ListChangedType.Reset, -1);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public void ResetItem(int position)
        {
            try
            {
                FireListChanged(ListChangedType.ItemChanged, position);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }


        private void FireListChanged(ListChangedType type, int index)
        {
            try
            {
                if (this.raiseListChangedEvents)
                {
                    OnListChanged(new ListChangedEventArgs(type, index));
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }



        protected virtual void ClearItems()
        {
            try
            {
                EndNew(addNewPos);

                if (this.raiseItemChangedEvents)
                {
                    foreach (T item in this.Items)
                    {
                        UnhookPropertyChanged(item);
                    }
                }

                items.Clear();
                FireListChanged(ListChangedType.Reset, -1);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        protected virtual void InsertItem(int index, T item)
        {
            try
            {
                EndNew(addNewPos);
                items.Insert(index, item);

                if (this.raiseItemChangedEvents)
                {
                    HookPropertyChanged(item);
                }

                FireListChanged(ListChangedType.ItemAdded, index);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        protected virtual void RemoveItem(int index)
        {
            try
            {
                if (!this.allowRemove && !(this.addNewPos >= 0 && this.addNewPos == index))
                {
                    throw new NotSupportedException();
                }

                EndNew(addNewPos);

                if (this.raiseItemChangedEvents)
                {
                    UnhookPropertyChanged(this[index]);
                }

                items.RemoveAt(index);
                FireListChanged(ListChangedType.ItemDeleted, index);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        protected virtual void SetItem(int index, T item)
        {

            try
            {
                if (this.raiseItemChangedEvents)
                {
                    UnhookPropertyChanged(this[index]);
                }

                items[index] = item;

                if (this.raiseItemChangedEvents)
                {
                    HookPropertyChanged(item);
                }

                FireListChanged(ListChangedType.ItemChanged, index);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public virtual void CancelNew(int itemIndex)
        {
            try
            {
                if (addNewPos >= 0 && addNewPos == itemIndex)
                {
                    RemoveItem(addNewPos);
                    addNewPos = -1;
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public virtual void EndNew(int itemIndex)
        {
            try
            {
                if (addNewPos >= 0 && addNewPos == itemIndex)
                {
                    addNewPos = -1;
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public T AddNew()
        {
            try
            {
                return (T)((this as IBindingList).AddNew());
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        object IBindingList.AddNew()
        {
            try
            {
                object newItem = AddNewCore();

                addNewPos = (newItem != null) ? IndexOf((T)newItem) : -1;

                return newItem;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        private bool AddingNewHandled
        {
            get
            {
                return onAddingNew != null && onAddingNew.GetInvocationList().Length > 0;
            }
        }

        protected virtual object AddNewCore()
        {

            try
            {
                object newItem = FireAddingNew();


                if (newItem == null)
                {

                    Type type = typeof(T);
                    newItem = SecureCreateInstance(type);
                }

                Add((T)newItem);

                return newItem;
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        public bool AllowNew
        {
            get
            {
                if (userSetAllowNew || allowNew)
                {
                    return this.allowNew;
                }
                return AddingNewHandled;
            }
            set
            {
                try
                {
                    bool oldAllowNewValue = AllowNew;
                    userSetAllowNew = true;
                    this.allowNew = value;
                    if (oldAllowNewValue != value)
                    {
                        FireListChanged(ListChangedType.Reset, -1);
                    }
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        bool IBindingList.AllowNew
        {
            get
            {
                return AllowNew;
            }
        }

        public bool AllowEdit
        {
            get
            {
                return this.allowEdit;
            }
            set
            {
                try
                {
                    if (this.allowEdit != value)
                    {
                        this.allowEdit = value;
                        FireListChanged(ListChangedType.Reset, -1);
                    }
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        bool IBindingList.AllowEdit
        {
            get
            {
                return AllowEdit;
            }
        }

        public bool AllowRemove
        {
            get
            {
                return this.allowRemove;
            }
            set
            {
                try
                {
                    if (this.allowRemove != value)
                    {
                        this.allowRemove = value;
                        FireListChanged(ListChangedType.Reset, -1);
                    }
                }
                catch (Exception exc)
                {
                    LogException(exc, MethodBase.GetCurrentMethod());
                    throw;
                }
            }
        }

        bool IBindingList.AllowRemove
        {
            get
            {
                return AllowRemove;
            }
        }

        bool IBindingList.SupportsChangeNotification
        {
            get
            {
                return SupportsChangeNotificationCore;
            }
        }

        protected virtual bool SupportsChangeNotificationCore
        {
            get
            {
                return true;
            }
        }

        bool IBindingList.SupportsSearching
        {
            get
            {
                return SupportsSearchingCore;
            }
        }

        protected virtual bool SupportsSearchingCore
        {
            get
            {
                return false;
            }
        }

        bool IBindingList.SupportsSorting
        {
            get
            {
                return SupportsSortingCore;
            }
        }

        protected virtual bool SupportsSortingCore
        {
            get
            {
                return false;
            }
        }

        bool IBindingList.IsSorted
        {
            get
            {
                return IsSortedCore;
            }
        }

        protected virtual bool IsSortedCore
        {
            get
            {
                return false;
            }
        }

        PropertyDescriptor IBindingList.SortProperty
        {
            get
            {
                return SortPropertyCore;
            }
        }

        protected virtual PropertyDescriptor SortPropertyCore
        {
            get
            {
                return null;
            }
        }

        ListSortDirection IBindingList.SortDirection
        {
            get
            {
                return SortDirectionCore;
            }
        }

        protected virtual ListSortDirection SortDirectionCore
        {
            get
            {
                return ListSortDirection.Ascending;
            }
        }

        void IBindingList.ApplySort(PropertyDescriptor prop, ListSortDirection direction)
        {
            try
            {
                ApplySortCore(prop, direction);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        protected virtual void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            throw new NotSupportedException();
        }

        void IBindingList.RemoveSort()
        {
            try
            {
                RemoveSortCore();
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        protected virtual void RemoveSortCore()
        {
            throw new NotSupportedException();
        }

        int IBindingList.Find(PropertyDescriptor prop, object key)
        {
            return FindCore(prop, key);
        }

        protected virtual int FindCore(PropertyDescriptor prop, object key)
        {
            throw new NotSupportedException();
        }

        void IBindingList.AddIndex(PropertyDescriptor prop)
        {

        }

        void IBindingList.RemoveIndex(PropertyDescriptor prop)
        {

        }


        private void HookPropertyChanged(T item)
        {
            try
            {
                INotifyPropertyChanged inpc = (item as INotifyPropertyChanged);

                if (null != inpc)
                {
                    if (propertyChangedEventHandler == null)
                    {
                        propertyChangedEventHandler = new PropertyChangedEventHandler(ElementPropertyChangedHandler);
                    }
                    inpc.PropertyChanged += propertyChangedEventHandler;
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        private void UnhookPropertyChanged(T item)
        {
            try
            {
                INotifyPropertyChanged inpc = (item as INotifyPropertyChanged);

                if (null != inpc && null != propertyChangedEventHandler)
                {
                    inpc.PropertyChanged -= propertyChangedEventHandler;
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        void ElementPropertyChangedHandler(object sender, PropertyChangedEventArgs e)
        {
            try
            {
                if (this.RaiseListChangedEvents)
                {
                    if (sender == null || e == null || string.IsNullOrEmpty(e.PropertyName))
                    {
                        ResetBindings();
                    }
                    else
                    {
                        T item;

                        try
                        {
                            item = (T)sender;
                        }
                        catch (InvalidCastException)
                        {
                            ResetBindings();
                            return;
                        }

                        int pos = lastChangeIndex;

                        if (pos < 0 || pos >= Count || !this[pos].Equals(item))
                        {
                            pos = this.IndexOf(item);
                            lastChangeIndex = pos;
                        }

                        if (pos == -1)
                        {
                            UnhookPropertyChanged(item);
                            ResetBindings();
                        }
                        else
                        {
                            if (this.itemTypeProperties == null)
                            {
                                itemTypeProperties = TypeDescriptor.GetProperties(typeof(T));
                                if (this.itemTypeProperties == null)
                                {
                                    // TODO: Log this condition
                                }
                            }

                            PropertyDescriptor pd = itemTypeProperties.Find(e.PropertyName, true);
                            ListChangedEventArgs args = new ListChangedEventArgs(ListChangedType.ItemChanged, pos, pd);
                            OnListChanged(args);
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        bool IRaiseItemChangedEvents.RaisesItemChangedEvents
        {
            get
            {
                return this.raiseItemChangedEvents;
            }
        }




        private static ReflectionPermission MemberAccessPermission
        {
            get
            {
                if (memberAccessPermission == null)
                {
                    memberAccessPermission = new ReflectionPermission(ReflectionPermissionFlag.MemberAccess);
                }
                return memberAccessPermission;
            }
        }

        private static ReflectionPermission RestrictedMemberAccessPermission
        {
            get
            {
                if (restrictedMemberAccessPermission == null)
                {
                    restrictedMemberAccessPermission = new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess);
                }
                return restrictedMemberAccessPermission;
            }
        }


        private static void DemandReflectionAccess(Type type)
        {
            try
            {
                MemberAccessPermission.Demand();
            }
            catch (SecurityException)
            {
                DemandGrantSet(type.Assembly);
            }
        }


        [SecuritySafeCritical]
        private static void DemandGrantSet(Assembly assembly)
        {
            PermissionSet targetGrantSet = assembly.PermissionSet;
            targetGrantSet.AddPermission(RestrictedMemberAccessPermission);
            targetGrantSet.Demand();
        }


        internal static object SecureCreateInstance(Type type)
        {
            return SecureCreateInstance(type, null, false);
        }

        private static bool HasReflectionPermission(Type type)
        {
            try
            {
                DemandReflectionAccess(type);
                return true;
            }
            catch (SecurityException)
            {
            }

            return false;
        }

        private static object SecureCreateInstance(Type type, object[] args, bool allowNonPublic)
        {
            try
            {
                if (type == null)
                {
                    throw new ArgumentNullException("type");
                }

                BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;

                if (!type.IsVisible)
                {
                    DemandReflectionAccess(type);
                }
                else if (allowNonPublic && !HasReflectionPermission(type))
                {
                    allowNonPublic = false;
                }

                if (allowNonPublic)
                {
                    flags |= BindingFlags.NonPublic;
                }

                return Activator.CreateInstance(type, flags, null, args, null);
            }
            catch (Exception exc)
            {
                LogException(exc, MethodBase.GetCurrentMethod());
                throw;
            }
        }

        [NonSerialized()]
        private PropertyDescriptorCollection properties;


        public virtual PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
        {
            PropertyDescriptorCollection pdc;

            if (listAccessors != null && listAccessors.Length > 0)
            {
                pdc = ListBindingHelper.GetListItemProperties(listAccessors[0].PropertyType);
            }
            else
            {
                if (properties == null)
                {
                    properties = TypeDescriptor.GetProperties(typeof(T), new Attribute[] { new BrowsableAttribute(true) });

                }
                pdc = properties;
            }

            return pdc;
        }

        public string GetListName(PropertyDescriptor[] listAccessors)
        {
            return typeof(T).Name;
        }


    }
}

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
Architect Sea Surveillance AS
Norway Norway
Chief Architect - Sea Surveillance AS.

Specializing in integrated operations and high performance computing solutions.

I’ve been fooling around with computers since the early eighties, I’ve even done work on CP/M and MP/M.

Wrote my first “real” program on a BBC micro model B based on a series in a magazine at that time. It was fun and I got hooked on this thing called programming ...

A few Highlights:

  • High performance application server development
  • Model Driven Architecture and Code generators
  • Real-Time Distributed Solutions
  • C, C++, C#, Java, TSQL, PL/SQL, Delphi, ActionScript, Perl, Rexx
  • Microsoft SQL Server, Oracle RDBMS, IBM DB2, PostGreSQL
  • AMQP, Apache qpid, RabbitMQ, Microsoft Message Queuing, IBM WebSphereMQ, Oracle TuxidoMQ
  • Oracle WebLogic, IBM WebSphere
  • Corba, COM, DCE, WCF
  • AspenTech InfoPlus.21(IP21), OsiSoft PI


More information about what I do for a living can be found at: harlinn.com or LinkedIn

You can contact me at espen@harlinn.no

Comments and Discussions