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;
}
}
}