BaseGenericDataCollectionView.cs :  » Persistence-Frameworks » Data-Holder » DataHolder » Containers » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Persistence Frameworks » Data Holder 
Data Holder » DataHolder » Containers » BaseGenericDataCollectionView.cs
/*
 * Namespace Summary
 * Copyright (C) 2005+ Bogdan Damian Constantin
 * E-Mail: damianbcpetro@gmail.com
 * WEB: http://www.sourceforge.net/projects/dataholder
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License 2.1 or later, as
 * published by the Free Software Foundation. See the included License.txt
 * or http://www.gnu.org/copyleft/lesser.html for details.
 *
 */

using System;
using System.Collections;
using System.ComponentModel;
using System.Reflection;
using DataHolder.Containers.Property;

namespace DataHolder.Containers{
    public delegate void SortChangedDelegate(Property.GenericDataProperty property, ListSortDirection direction);
    public enum GenericDataCollectionViewState { Current = 1, All = 2 };  


    public abstract class BaseGenericDataCollectionView:IDisposable, IBindingList, ITypedList
  {
    public event GenericDataCollectionModified CollectionModified;
    public event GenericDataPropertyModified PropertyModified;
    public event SortChangedDelegate SortChanged;

    #region constructors
    public BaseGenericDataCollectionView(GenericDataCollection gecoll)
    {
            l_AllowNew = false;
            lIsSorted = false;
            lAllowRemove = false;
            lAllowEdit = false;
      lGEEntitiesState = GenericDataCollectionViewState.Current;
      innerCollection = gecoll;
            Initialize();
    }

        protected void Initialize()
        {
            SetPositions();
            innerCollection.CollectionModified += new GenericDataCollectionModified(innerCollection_CollectionModified);
            innerCollection.PropertyModified += new GenericDataPropertyModified(innerCollection_PropertyModified);
        }

    #endregion

        protected GenericDataCollection innerCollection;
        protected bool l_AllowNew, lIsSorted, lAllowRemove, lAllowEdit;
        protected ListSortDirection lSortDirection;

        protected int[] Positions;
        protected PropertyDescriptor lSortProperty = null;
        protected GenericDataCollectionViewState lGEEntitiesState;


    /// <summary>
    /// states of the data that will be visible through this view
    /// if you wan to see only data that is in a specific state please modify this collection
    /// </summary>
    public GenericDataCollectionViewState GEEntitiesState
    {
      get
      {
        return lGEEntitiesState;
      }
      set
      {
        lGEEntitiesState = value;
      }
    }

    public System.Data.DataTable ToDataTable()
    {
      System.Data.DataTable tb = new System.Data.DataTable();
      Property.PropertyCollection  Properties = GenericData.TCollection.GetProperties(innerCollection.GenericDataType);
      for(int i = 0; i < Properties.Count; i++)
        tb.Columns.Add(Properties[i].PropertyName, Properties[i].PropertyType);
      for(int i = 0; i < this.Count; i++)
      {
        System.Data.DataRow row = tb.NewRow();
        for(int j = 0; j < Properties.Count; j++)
        {
                    GenericData tmpge = innerCollection.GetObjectAt(Positions[i]);
          row[j] = tmpge[j];
        }
        tb.Rows.Add(row);
      }
      return tb;
    }

    #region internall methods

    protected void SetPositions()
    {
      int [] tmpPositions = new int [innerCollection.Count];
      int i = 0, j = 0;
      for(i = 0; i < innerCollection.Count; i++)
        if(lGEEntitiesState != GenericDataCollectionViewState.Current
          || ( innerCollection.GetObjectAt(i).State != GenericDataState.Deleted
          && innerCollection.GetObjectAt(i).State != GenericDataState.Detached))
        {
          tmpPositions[j] = i;
          j++;
        }
      Positions = new int [j];
      for(i = 0; i < j; i++)
        Positions[i] = tmpPositions[i];
      tmpPositions = null;

      if(lSortProperty != null)
        DoSort(lSortProperty, lSortDirection);
    }


    protected GenericDataProperty DoSort(PropertyDescriptor property, ListSortDirection direction)
    {
      PropertyCollection _Properties = GenericData.TCollection.GetProperties(innerCollection.GenericDataType);
      
      GenericDataProperty prop = _Properties[property.DisplayName];
      if(prop != null)
      {
        CollectionComparer cc = new CollectionComparer(this, (IComparer)prop, _Properties.IndexOf(property.DisplayName));
        Array.Sort(Positions,cc);
        cc = null;
      }
      _Properties = null;
      return prop;
    }

    protected int GetPositionBySource(int SourceCollectionIndex)
    {
      lock(this.innerCollection.SyncRoot)
      {
      for(int i = 0; i < Positions.Length; i++)
        if(SourceCollectionIndex == Positions[i])
          return i;
      }
      throw new Exception("index " + SourceCollectionIndex.ToString() +" not found");
    }
    #endregion

    #region IDisposable Members

    public void Dispose()
    {
      innerCollection = null;
      Positions = null;
      CollectionModified = null;
      PropertyModified = null;
      SortChanged = null;
      lSortProperty = null;
    }

    #endregion
  
    #region IBindingList Members

    public void AddIndex(PropertyDescriptor property)
    {
      throw new NotSupportedException();
    }

    public bool AllowNew
    {
      get{return l_AllowNew;}
      set{l_AllowNew = value;}
    }

    public void ApplySort(PropertyDescriptor property, ListSortDirection direction)
    {
      lSortProperty = property;
      lSortDirection = direction;
      GenericDataProperty prop = null;
      lock(this.innerCollection.SyncRoot)
      {
        prop = DoSort(property, direction);
      }
      ExecuteListChangedEvents(ListChangedType.Reset, property);
      lIsSorted = true;
      if(SortChanged != null)
        SortChanged(prop, direction);
    }

    public void Sort(string ColumnName, ListSortDirection direction)
    {
      PropertyCollection pcol = GenericData.TCollection.GetProperties(innerCollection.GenericDataType);
      GenericDataPropertyDescriptor pp = new GenericDataPropertyDescriptor(pcol, ColumnName, null);
      ApplySort(pp, direction);
    }

    public PropertyDescriptor SortProperty
    {
      get
      {
        return lSortProperty;
      }
    }

    #region Find Implementation
    public int Find(PropertyDescriptor property, object key)
    {
      GenericDataPropertyDescriptor geproperty = property as GenericDataPropertyDescriptor;
      if(geproperty != null)
        return Find(geproperty.PropertyCollection, geproperty.PropertyIndex, key);
      //for properties defined by user reflection will be used
      for(int i =0 ;i < this.Count; i++)
        if(property.GetValue(innerCollection.GetObjectAt(Positions[i])).Equals(key))
          return i;
        
      return 0;
    }

    private int Find(PropertyCollection pcoll, int PropertyIndex, object key)
    {
      if(pcoll[PropertyIndex] is IComparer)
      {
        IComparer comp = (IComparer)pcoll[PropertyIndex];
        for(int i =0 ;i < this.Count; i++)
          if(comp.Compare(key, (innerCollection.GetObjectAt(Positions[i]))[PropertyIndex]) == 0)
            return i;
        return 0;
      }    
      else
        return 0;
    }

    public int Find(string PropertyName, object key)
    {
      PropertyCollection pcoll = GenericData.TCollection.GetProperties(innerCollection.GenericDataType);
      int PropertyIndex = pcoll.IndexOf(PropertyName);
      #if FULLCHECKING
      if(PropertyIndex < 0)
        throw new DataHolder.Exceptions.DataHolderPropertyException("Can't find key " + key.ToString() + " by " + PropertyName + " because thr property doesn't exists in " + innerCollection.GenericDataType.ToString() );      
      #endif
      return Find(pcoll, PropertyIndex, key);
    }
    #endregion

    public bool SupportsSorting
    {
      get
      {
        return true;
      }
    }

    public bool IsSorted
    {
      get
      {
        return lIsSorted;
      }
    }

    public bool AllowRemove
    {
      get
      {
        return lAllowRemove;
      }
      set
      {
        lAllowRemove = value;
      }
    }

    public bool SupportsSearching
    {
      get
      {
        return true;
      }
    }

    public ListSortDirection SortDirection
    {
      get
      {
        return lSortDirection;
      }
      set
      {
        lSortDirection = value;
      }
    }

    private void ExecuteListChangedEvents(ListChangedType lct, PropertyDescriptor pdesc)
    {
      if(ListChangedEvents != null)
      {
        foreach(ListChangedEventHandler lev in ListChangedEvents)
          lev(this, new ListChangedEventArgs(lct, pdesc));
      }
    }

    private void ExecuteListChangedEvents(ListChangedType lct, int index)
    {
      if(ListChangedEvents != null)
      {
        foreach(ListChangedEventHandler lev in ListChangedEvents)
          lev(this, new ListChangedEventArgs(lct, index));
      }
    }


    private ArrayList ListChangedEvents = null;
    public event ListChangedEventHandler ListChanged
    {
      add
      {
        if(ListChangedEvents == null)
          ListChangedEvents = new ArrayList(1);
        ListChangedEvents.Add(value);
      }
      remove
      {
        ListChangedEvents.Remove(value);
        if(ListChangedEvents.Count == 0)
          ListChangedEvents = null;
      }
    }

    public bool SupportsChangeNotification
    {
      get
      {
        return true;
      }
    }

        public void RemoveSort()
        {
            lock (this.innerCollection.SyncRoot)
            {
                lSortProperty = null;
                SetPositions();
            }
        }

    public object AddNew()
    {
      return innerCollection.AddNew();
    }

    public bool AllowEdit
    {
      get
      {
        return lAllowEdit;
      }
    }

    public void RemoveIndex(PropertyDescriptor property)
    {
      throw new NotSupportedException();
    }

    #endregion

    #region IList Members

    bool IList.IsReadOnly
    {
      get
      {
        return false;
      }
    }

        object IList.this[int index]
        {
            get
            {
                return innerCollection.GetObjectAt(Positions[index]);
            }
            set
            {
                innerCollection.SetObjectAt(Positions[index], (GenericData)value);
            }
        }

    public void RemoveAt(int index)
    {
      innerCollection.RemoveAt(Positions[index]);
    }

        void IList.Insert(int index, object value)
        {
            innerCollection.Insert(Positions[index], (GenericData)value);
        }

        void IList.Remove(object value)
        {
            innerCollection.Remove((GenericData)value);
        }

        bool IList.Contains(object value)
        {
            return innerCollection.Contains((GenericData)value);
        }

    public void Clear()
    {
      innerCollection.Clear();
    }

        int IList.IndexOf(object value)
    {
      for(int i = 0; i < Positions.Length; i++)
        if(value == innerCollection.GetObjectAt(Positions[i]))
          return i;
      return -1;
    }

        int IList.Add(object value)
        {
            innerCollection.Add((GenericData)value);
            return 1;
        }

    bool IList.IsFixedSize
    {
      get
      {
        return false;
      }
    }

    #endregion

    #region ICollection Members

    public bool IsSynchronized
    {
      get
      {
        return true;
      }
    }

    public int Count
    {
      get
      {
        return Positions.Length;
      }
    }

        void ICollection.CopyTo(Array array, int index)
        {
            innerCollection.CopyTo((GenericData[])array, index);
        }

    public object SyncRoot
    {
      get
      {
        return this;
      }
    }

    #endregion

    #region IEnumerable Members

    public System.Collections.IEnumerator GetEnumerator()
    {
      return new GenericDataEnumerator(this);
    }

    #endregion

    #region CollectionComparer
        internal class CollectionComparer : IComparer
    {
            private BaseGenericDataCollectionView colview;
      private IComparer _gep;
      private int _Position;

            public CollectionComparer(BaseGenericDataCollectionView cv, IComparer gep, int Position)
      {
        colview = cv;
        _gep = gep;
        _Position = Position;
      }
      
      public int Compare(object x, object y)
      {
        object ox = colview.innerCollection.GetObjectAt((int)x)[_Position];
        object oy = colview.innerCollection.GetObjectAt((int)y)[_Position];
        int XGraterthanY = _gep.Compare(ox, oy);
        if(colview.SortDirection == System.ComponentModel.ListSortDirection.Ascending)
          return XGraterthanY;
        else
          return XGraterthanY * -1;
      }
    }

    #endregion

    #region ITypedList Members

    private void ClearInternalPropertiesFromPropertyDescriptor(ArrayList pdc)
    {
      for(int pi = pdc.Count -1; pi >= 0; pi--)
      {
        PropertyDescriptor p = (PropertyDescriptor)pdc[pi];
        if(p.Name.Equals("SuppressEvents")
          || p.Name.Equals("Properties")
          || p.Name.Equals("Parent")
          || p.Name.Equals("NewPropertyCollection"))
          pdc.RemoveAt(pi);
      }
    }

    public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
    {
      PropertyDescriptorCollection pdctmp = TypeDescriptor.GetProperties(innerCollection.GenericDataType);
      ArrayList pdc = new ArrayList(pdctmp.Count);
      ClearInternalPropertiesFromPropertyDescriptor(pdc);
      pdc.AddRange(pdctmp);
      PropertyCollection pcol = GenericData.TCollection.GetProperties(innerCollection.GenericDataType);
      PropertyDescriptor [] pdesccollection = new PropertyDescriptor[pcol.Count];
      for(int i = 0; i < pcol.Count; i++)
      {
        pdesccollection[i] = new GenericDataPropertyDescriptor(pcol, pcol[i].PropertyName,null);
        for(int pi = 0; pi < pdc.Count; pi++)
          if(pcol[i].PropertyName.Equals(((PropertyDescriptor)pdc[pi]).Name))
          {
            pdc.RemoveAt(pi);
            break;
          }

      }
      
      PropertyDescriptor [] res = new PropertyDescriptor[pcol.Count+pdc.Count];
      pdesccollection.CopyTo(res,0);
      pdc.CopyTo(res, pdesccollection.Length);

      return new PropertyDescriptorCollection(res);
    }

    public string GetListName(PropertyDescriptor[] listAccessors)
    {
      return string.Empty;
    }

    #endregion

    #region Events Action
    private void innerCollection_CollectionModified(GenericData ge, GenericDataCollectionEventType evType, int index)
    {
      lock(this.SyncRoot)
      {
      if(evType == GenericDataCollectionEventType.Clear)
      {
          SetPositions();
        ExecuteListChangedEvents(ListChangedType.Reset,0);
        if(CollectionModified != null)
          CollectionModified(ge, evType, 0);
        return;
      }
      else
      {
        int position = -1;
        if(evType == GenericDataCollectionEventType.Deleted)
          position = GetPositionBySource(index);
        SetPositions();
        if(evType == GenericDataCollectionEventType.Added)
        {
          if(lGEEntitiesState == GenericDataCollectionViewState.All
            || ge.State != GenericDataState.Detached)
          {
            position = GetPositionBySource(index);
            ExecuteListChangedEvents(ListChangedType.ItemAdded,position);
          }
        }
        else if(evType == GenericDataCollectionEventType.Modified)
        {
          position = GetPositionBySource(index);
          ExecuteListChangedEvents(ListChangedType.ItemChanged,position);
        }
        else if(evType == GenericDataCollectionEventType.Deleted)
          ExecuteListChangedEvents(ListChangedType.ItemDeleted,position);

        if(evType != GenericDataCollectionEventType.Reset
          && CollectionModified != null)
          CollectionModified(ge, evType, position);
      }
    }
    }

    private void innerCollection_PropertyModified(GenericData ge, GEChangeEventArgs args)
    {
      lock(this.innerCollection.SyncRoot)
      {
      if(SortProperty != null)
        DoSort(SortProperty, SortDirection);
      ExecuteListChangedEvents(ListChangedType.ItemChanged, ((IList)this).IndexOf(ge));
      if(PropertyModified != null)
        PropertyModified(ge,args);
    }
    }
    #endregion
  }

}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.