/*
* 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.Data;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Runtime.Serialization;
using DataHolder.Containers.Property;
using DataHolder.Containers.ParentActions;
namespace DataHolder.Containers{
/// <summary>
/// Summary description for GenericDataCollection.
/// </summary>
[Serializable]
public abstract class GenericDataCollection : ICollection<GenericData>, IEnumerable<GenericData>,
IDeserializationCallback, ParentActions.IGenericDataParent,
IListSource, IDisposable, ISerializable, IXmlSerializable
{
protected List<GenericData> l_CurrentRecords = new List<GenericData>();
protected ParentActions.IGenericDataParent l_Parent;
public event GenericDataCollectionModified CollectionModified;
public event GenericDataPropertyModified PropertyModified;
public GenericDataCollection()
{
//todo
}
/// <summary>
/// This property must be overrided, and must return the type for the class derived from
/// genericData
/// </summary>
public virtual Type GenericDataType
{
get
{
throw new Exceptions.DataHolderException("GenericDataType property should be overrided");
}
}
#region ICloneable Members
public GenericDataCollection Clone()
{
GenericDataCollection clone = (GenericDataCollection)Activator.CreateInstance(this.GetType());
for(int cp=0;cp < this.Count; cp++)
clone.Add(this.GetObjectAt(cp).Clone());
return clone;
}
#endregion
#region Collection Actions
public GenericData GetObjectAt(int index)
{
return l_CurrentRecords[index];
}
public void SetObjectAt(int index, GenericData value)
{
GenericData oldge = l_CurrentRecords[index];
l_CurrentRecords[index] = value;
if(CollectionModified != null)
CollectionModified(value, GenericDataCollectionEventType.Modified, index);
OnSet(index, oldge, value);
}
public void CopyTo(GenericData [] array, int index)
{
l_CurrentRecords.CopyTo(array, index);
}
public int Count
{
get
{
return l_CurrentRecords.Count;
}
}
public bool IsSynchronized
{
get
{
return true;
}
}
public object SyncRoot
{
get
{
return this;
}
}
#endregion
#region Virtual Members
protected virtual void OnRemove(int index, GenericData value)
{
if(CollectionModified != null)
CollectionModified(value, GenericDataCollectionEventType.Deleted, index);
if(l_Parent != null)
l_Parent.GenericDataCollectionModified(this, new Containers.GECollectionChangeEventArgs(null, index));
}
protected virtual void OnInsert(int index, GenericData value)
{
if(CollectionModified != null)
CollectionModified(value, GenericDataCollectionEventType.Added, index);
if(l_Parent != null)
l_Parent.GenericDataCollectionModified(this, new Containers.GECollectionChangeEventArgs(null, index));
}
protected virtual void OnSet(int index, GenericData oldValue, GenericData newValue)
{
}
protected virtual void OnValidate(GenericData value)
{
}
#endregion
#region GECOllectioActions
public GenericData AddNew()
{
GenericData ge = (GenericData)Activator.CreateInstance(GenericDataType);
this.Add(ge);
return ge;
}
public void EndEdit()
{
foreach(GenericData ge in this)
ge.EndEdit(false);
if(CollectionModified != null)
CollectionModified(null, Containers.GenericDataCollectionEventType.Clear, 0);
}
public void CancelEdit()
{
foreach(GenericData ge in this)
ge.CancelEdit(false);
if(CollectionModified != null)
CollectionModified(null, Containers.GenericDataCollectionEventType.Clear, 0);
}
public void AcceptChanges()
{
AcceptChanges(true);
}
public void AcceptChanges(bool CallEvents)
{
for(int i = 0; i < l_CurrentRecords.Count; i++)
{
GenericData ge = l_CurrentRecords[i];
if(ge.State == GenericDataState.Deleted)
{
l_CurrentRecords.RemoveAt(i);
i--;
}
else
ge.AcceptChanges(CallEvents);
}
if(CallEvents && CollectionModified != null)
CollectionModified(null, Containers.GenericDataCollectionEventType.Reset, 0);
}
public void RejectChanges()
{
for (int i = 0; i < l_CurrentRecords.Count; i++)
{
GenericData ge = l_CurrentRecords[i];
if (ge.State == GenericDataState.Added || ge.State == GenericDataState.Detached)
{
l_CurrentRecords.RemoveAt(i);
i--;
}
else
ge.RejectChanges();
}
if (CollectionModified != null)
CollectionModified(null, Containers.GenericDataCollectionEventType.Clear, 0);
}
public DataTable ToDataTable()
{
DataTable tb = new DataTable();
Property.PropertyCollection Properties = GenericData.TCollection.GetProperties(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++)
{
DataRow row = tb.NewRow();
for(int j = 0; j < Properties.Count; j++)
{
GenericData tmpge = GetObjectAt(i);
row[j] = tmpge[j];
}
tb.Rows.Add(row);
}
return tb;
}
#endregion
#region IList Members
public void Add(GenericData ge)
{
ge.Parent =this;
l_CurrentRecords.Add(ge);
OnInsert(l_CurrentRecords.Count-1, ge);
}
public void Insert(int index, GenericData ge)
{
ge.Parent =this;
l_CurrentRecords.Insert(index, ge);
OnInsert(index, ge);
}
public bool Remove(GenericData ge)
{
int index = l_CurrentRecords.IndexOf(ge);
bool ret = l_CurrentRecords.Remove(ge);
if(ge.State != GenericDataState.Detached)
OnRemove(index, ge);
return ret;
}
public void RemoveAt(int index)
{
GenericData ge = l_CurrentRecords[index];
l_CurrentRecords.RemoveAt(index);
OnRemove(index, ge);
}
public bool Contains(GenericData value)
{
return l_CurrentRecords.Contains(value);
}
public int IndexOf(GenericData value)
{
return l_CurrentRecords.IndexOf(value);
}
public void Clear()
{
lock(this.SyncRoot)
{
l_CurrentRecords.Clear();
}
if(CollectionModified != null)
CollectionModified(null, GenericDataCollectionEventType.Clear, 0);
if(l_Parent != null)
l_Parent.GenericDataCollectionModified(this, new Containers.GECollectionChangeEventArgs(null, 0));
}
public bool IsReadOnly
{
get { return false; }
}
#endregion
#region Serialization
public const string CurrentRecordsSerializationLabel = "CurrentRecords";
public const string ItemLabel = "Item";
private GenericData[] DeserializedCurrentRecords = null;
internal bool InSerialization = false;
#region ISerializable Members
public GenericDataCollection(SerializationInfo info, StreamingContext context)
{
DeserializedCurrentRecords = (GenericData [])info.GetValue(CurrentRecordsSerializationLabel, typeof(Array));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
SerializationHelper srinfo = null;
if(!InSerialization)
{
srinfo = new SerializationHelper();
SerializationHelper.CollectionGenericDataPreSerializatonAction(this, srinfo);
}
info.AddValue(CurrentRecordsSerializationLabel, l_CurrentRecords.ToArray());
if(srinfo != null)
{
srinfo.ClearSerialization = true;
SerializationHelper.CollectionGenericDataPreSerializatonAction(this, srinfo);
}
}
#endregion
#region IXmlSerializable Members
public void ReadXml(XmlReader reader)
{
if(reader.NodeType == XmlNodeType.None)
reader.Read();
if(reader.NodeType == XmlNodeType.Element)
{
// if(reader.Name.Equals(this.GetType().ToString()))
// {
reader.Read();
while(reader.IsStartElement(ItemLabel))
{
GenericData ge = (GenericData)Activator.CreateInstance(this.GenericDataType);
ge.ReadXml(reader);
Add(ge);
//read end element
reader.Read();
}
// }
//now read the end of element
// reader.Read();
}
}
public void WriteXml(XmlWriter writer)
{
SerializationHelper srinfo = null;
if(!InSerialization)
{
srinfo = new SerializationHelper();
SerializationHelper.CollectionGenericDataPreSerializatonAction(this, srinfo);
}
// writer.WriteStartElement(this.GetType().ToString());
foreach(GenericData ge in l_CurrentRecords)
{
writer.WriteStartElement(ItemLabel);
ge.WriteXml(writer);
writer.WriteEndElement();
}
// writer.WriteEndElement();
if(srinfo != null)
{
srinfo.ClearSerialization = true;
SerializationHelper.CollectionGenericDataPreSerializatonAction(this, srinfo);
}
}
public System.Xml.Schema.XmlSchema GetSchema()
{
// TODO: Add GenericData.GetSchema implementation
return null;
}
#endregion
#endregion
#region IDeserializationCallback Members
public void OnDeserialization(object sender)
{
l_CurrentRecords.AddRange(DeserializedCurrentRecords);
DeserializedCurrentRecords = null;
}
#endregion
#region IEnumerable Members
IEnumerator<GenericData> IEnumerable<GenericData>.GetEnumerator()
{
return l_CurrentRecords.GetEnumerator();
}
public IEnumerator GetEnumerator()
{
return l_CurrentRecords.GetEnumerator();
}
#endregion
#region IGenericDataParent Members
//TODO ADD GENERIC PROCEDURES HERE I THINK
public void GenericDataChildModified(GenericData ge, DataHolder.Containers.GEChangeEventArgs args)
{
if(args.EventType == GEChangeEventArgs.ChangeEventType.Delete)
{
if(ge.State == GenericDataState.Deleted)
this.OnRemove(IndexOf(ge), (GenericData)ge);
else
Remove(ge);
}
else if(args.EventType == GEChangeEventArgs.ChangeEventType.DetachedFieldAdded)
OnInsert(IndexOf(ge), ge);
else
{
if(PropertyModified != null)
PropertyModified(ge, args);
if(l_Parent != null)
l_Parent.GenericDataCollectionModified(this, new GECollectionChangeEventArgs(args.Property,this.IndexOf(ge)));
}
}
public void GenericDataCollectionModified(GenericDataCollection gecoll, DataHolder.Containers.GECollectionChangeEventArgs args)
{
}
public ParentActions.IGenericDataParent Parent
{
get
{
return l_Parent;
}
set
{
l_Parent = value;
}
}
#endregion
#region IListSource Members
public IList GetList()
{
return GetDefaultView();
}
public bool ContainsListCollection
{
get
{
return false;
}
}
protected virtual BaseGenericDataCollectionView GetDefaultView()
{
throw new Exceptions.DataHolderException("Please implement the GetDefaultView function!");
}
#endregion
#region IDisposable Members
public void Dispose()
{
if(l_CurrentRecords != null)
l_CurrentRecords.Clear();
l_Parent = null;
if(CollectionModified != null)
CollectionModified = null;
if(PropertyModified != null)
PropertyModified = null;
}
protected virtual void OnDispose()
{
}
#endregion
}
}
|