Torna al Thread

:using System; using System.Collections.Generic; using System.Collections; using System.Text; using System.ComponentModel; namespace lemoncake.samples { public class BindingListView<T> : BindingList<T>, IBindingListView, IRaiseItemChangedEvents { private bool m_Sorted = false; private bool m_Filtered = false; private string m_FilterString = null; private ListSortDirection m_SortDirection = ListSortDirection.Ascending; private PropertyDescriptor m_SortProperty = null; private ListSortDescriptionCollection m_SortDescriptions = new ListSortDescriptionCollection(); private List<T> m_OriginalCollection = new List<T>(); public BindingListView() : base() { } public BindingListView(List<T> list) : base(list) { } protected override bool SupportsSearchingCore { get { return true; } } protected override int FindCore(PropertyDescriptor property, object key) { // Simple iteration: for (int i = 0; i < Count; i++) { T item = this[i]; if (property.GetValue(item).Equals(key)) { return i; } } return -1; // Not found // Alternative search implementation // using List.FindIndex: //Predicate<T> pred = delegate(T item) //{ // if (property.GetValue(item).Equals(key)) // return true; // else // return false; //}; //List<T> list = Items as List<T>; //if (list == null) // return -1; //return list.FindIndex(pred); } protected override bool SupportsSortingCore { get { return true; } } protected override bool IsSortedCore { get { return m_Sorted; } } protected override ListSortDirection SortDirectionCore { get { return m_SortDirection; } } protected override PropertyDescriptor SortPropertyCore { get { return m_SortProperty; } } protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction) { m_SortDirection = direction; m_SortProperty = property; SortComparer<T> comparer = new SortComparer<T>(property, direction); ApplySortInternal(comparer); } private void ApplySortInternal(SortComparer<T> comparer) { if (m_OriginalCollection.Count == 0) { m_OriginalCollection.AddRange(this); } List<T> listRef = this.Items as List<T>; if (listRef == null) return; listRef.Sort(comparer); m_Sorted = true; OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } protected override void RemoveSortCore() { if (!m_Sorted) return; Clear(); foreach (T item in m_OriginalCollection) { Add(item); } m_OriginalCollection.Clear(); m_SortProperty = null; m_SortDescriptions = null; m_Sorted = false; } void IBindingListView.ApplySort(ListSortDescriptionCollection sorts) { m_SortProperty = null; m_SortDescriptions = sorts; SortComparer<T> comparer = new SortComparer<T>(sorts); ApplySortInternal(comparer); } string IBindingListView.Filter { get { return m_FilterString; } set { m_FilterString = value; m_Filtered = true; UpdateFilter(); } } void IBindingListView.RemoveFilter() { if (!m_Filtered) return; m_FilterString = null; m_Filtered = false; m_Sorted = false; m_SortDescriptions = null; m_SortProperty = null; Clear(); foreach (T item in m_OriginalCollection) { Add(item); } m_OriginalCollection.Clear(); } ListSortDescriptionCollection IBindingListView.SortDescriptions { get { return m_SortDescriptions; } } bool IBindingListView.SupportsAdvancedSorting { get { return true; } } bool IBindingListView.SupportsFiltering { get { return true; } } protected virtual void UpdateFilter() { int equalsPos = m_FilterString.IndexOf('='); // Get property name string propName = m_FilterString.Substring(0, equalsPos).Trim(); // Get filter criteria string criteria = m_FilterString.Substring(equalsPos + 1, m_FilterString.Length - equalsPos - 1).Trim(); // Strip leading and trailing quotes criteria = criteria.Substring(1, criteria.Length - 2); // Get a property descriptor for the filter property PropertyDescriptor propDesc = TypeDescriptor.GetProperties(typeof(T))[propName]; if (m_OriginalCollection.Count == 0) { m_OriginalCollection.AddRange(this); } List<T> currentCollection = new List<T>(this); Clear(); /** * This implementation simulates a LIKE '%term%' and will * find your term within the field */ foreach (T item in currentCollection) { object value = propDesc.GetValue(item); // strip newline characters as it was causing issues with contains string sval = value.ToString().Replace("\n", "").Replace("\r", ""); if (sval.ToString().Contains(criteria)) { Add(item); } } /** * Original Implementation that acts like a normal filter * Only matches the whole field * foreach (T item in currentCollection) { object value = propDesc.GetValue(item); if (value.ToString().Equals(criteria)) { Add(item); } } */ } bool IBindingList.AllowNew { get { return CheckReadOnly(); } } bool IBindingList.AllowRemove { get { return CheckReadOnly(); } } private bool CheckReadOnly() { if (m_Sorted || m_Filtered) { return false; } else { return true; } } protected override void InsertItem(int index, T item) { foreach (PropertyDescriptor propDesc in TypeDescriptor.GetProperties(item)) { if (propDesc.SupportsChangeEvents) { propDesc.AddValueChanged(item, OnItemChanged); } } base.InsertItem(index, item); } protected override void RemoveItem(int index) { T item = Items[index]; PropertyDescriptorCollection propDescs = TypeDescriptor.GetProperties(item); foreach (PropertyDescriptor propDesc in propDescs) { if (propDesc.SupportsChangeEvents) { propDesc.RemoveValueChanged(item, OnItemChanged); } } base.RemoveItem(index); } void OnItemChanged(object sender, EventArgs args) { int index = Items.IndexOf((T)sender); OnListChanged(new ListChangedEventArgs( ListChangedType.ItemChanged, index)); } bool IRaiseItemChangedEvents.RaisesItemChangedEvents { get { return true; } } } class SortComparer<T> : IComparer<T> { private ListSortDescriptionCollection m_SortCollection = null; private PropertyDescriptor m_PropDesc = null; private ListSortDirection m_Direction = ListSortDirection.Ascending; public SortComparer(PropertyDescriptor propDesc, ListSortDirection direction) { m_PropDesc = propDesc; m_Direction = direction; } public SortComparer(ListSortDescriptionCollection sortCollection) { m_SortCollection = sortCollection; } int IComparer<T>.Compare(T x, T y) { if (m_PropDesc != null) // Simple sort { object xValue = m_PropDesc.GetValue(x); object yValue = m_PropDesc.GetValue(y); return CompareValues(xValue, yValue, m_Direction); } else if (m_SortCollection != null && m_SortCollection.Count > 0) { return RecursiveCompareInternal(x, y, 0); } else return 0; } private int CompareValues(object xValue, object yValue, ListSortDirection direction) { int retValue = 0; if (xValue is IComparable) // Can ask the x value { retValue = ((IComparable)xValue).CompareTo(yValue); } else if (yValue is IComparable) //Can ask the y value { retValue = ((IComparable)yValue).CompareTo(xValue); } // not comparable, compare String representations else if (!xValue.Equals(yValue)) { retValue = xValue.ToString().CompareTo(yValue.ToString()); } if (direction == ListSortDirection.Ascending) { return retValue; } else { return retValue * -1; } } private int RecursiveCompareInternal(T x, T y, int index) { if (index >= m_SortCollection.Count) return 0; // termination condition ListSortDescription listSortDesc = m_SortCollection[index]; object xValue = listSortDesc.PropertyDescriptor.GetValue(x); object yValue = listSortDesc.PropertyDescriptor.GetValue(y); int retValue = CompareValues(xValue, yValue, listSortDesc.SortDirection); if (retValue == 0) { return RecursiveCompareInternal(x, y, ++index); } else { return retValue; } } } }
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5