using System;
using System.Collections.Generic;
using System.Text;
using Ubik.Engine.Client;
using System.ComponentModel;
namespace StoresAndStockPricing.Controls{
public class BoundDataGridViewSource<T> : IBoundDataGridViewSource, IBindingList
where T : Individual
{
private Session _session;
private List<BoundDataGridViewColumn<T>> _columns = new List<BoundDataGridViewColumn<T>>();
private List<BoundDataGridViewRow<T>> _rows = new List<BoundDataGridViewRow<T>>();
private string _filter;
private bool _eventHandlersRegistered = false;
public delegate bool AffectsComponentDelegate(Session session, T value, Guid identity);
private AffectsComponentDelegate _affectsComponentDelegate;
private Type[] _affectedTypes;
public BoundDataGridViewSource(Session session)
: this(session, null, null)
{
}
public BoundDataGridViewSource(Session session, Type[] affectedTypes, AffectsComponentDelegate affectsComponentDelegate)
{
if (session == null)
throw new ArgumentNullException("session");
_session = session;
if (affectedTypes != null && affectsComponentDelegate == null ||
affectedTypes == null && affectsComponentDelegate != null)
{
throw new ArgumentException(BoundDataGridViewSourceResources.BothTypesAndDelegateMustBeProvided);
}
_affectedTypes = affectedTypes;
_affectsComponentDelegate = affectsComponentDelegate;
}
~BoundDataGridViewSource()
{
UnregisterEventHandlers();
}
public void OnSessionInsertEvent(Guid identity)
{
T newValue = (T) _session.SelectOne(typeof(T), identity);
if (_session.Test(newValue, UPathFilter))
{
BoundDataGridViewRow<T> newRow = new BoundDataGridViewRow<T>(newValue, _columns);
_rows.Add(newRow);
if (ListChanged != null)
ListChanged(this, new ListChangedEventArgs(ListChangedType.ItemAdded, _rows.IndexOf(newRow)));
}
}
public void OnSessionUpdateEvent(Guid identity)
{
foreach (BoundDataGridViewRow<T> row in _rows)
{
if (row.Value.Identity == identity ||
(_affectsComponentDelegate != null &&
_affectsComponentDelegate(_session, row.Value, identity)))
{
if (ListChanged != null)
ListChanged(this, new ListChangedEventArgs(ListChangedType.ItemChanged, _rows.IndexOf(row)));
}
}
}
public void OnSessionDeleteEvent(Guid identity)
{
foreach (BoundDataGridViewRow<T> row in _rows)
{
if (row.Value.Identity == identity)
{
ListChangedEventArgs lcea = new ListChangedEventArgs(ListChangedType.ItemDeleted, _rows.IndexOf(row));
_rows.Remove(row);
if (ListChanged != null)
ListChanged(this, lcea);
break; // assume for now rows are unique by identity
}
}
}
public IList<BoundDataGridViewColumn<T>> Columns
{
get
{
return _columns;
}
}
public string Filter
{
get
{
return _filter;
}
set
{
string oldValue = _filter;
try
{
_filter = value;
Load();
}
catch (Exception)
{
_filter = oldValue;
throw;
}
}
}
private string UPathFilter
{
get
{
if (string.IsNullOrEmpty(_filter))
return typeof(T).Name;
else
return typeof(T).Name + "[" + _filter + "]";
}
}
private void Load()
{
List<BoundDataGridViewRow<T>> oldRows = _rows;
try
{
_rows = new List<BoundDataGridViewRow<T>>();
IList<Individual> newRows = _session.Select(UPathFilter);
foreach (T row in newRows)
{
_rows.Add(new BoundDataGridViewRow<T>(row, _columns));
}
RegisterEventHandlers();
FireReset();
}
catch (Exception)
{
_rows = oldRows;
throw;
}
}
private void RegisterEventHandlers()
{
if (!_eventHandlersRegistered)
{
_session.AddInsertEventHandler(OnSessionInsertEvent, new Type[] { typeof(T) });
_session.AddDeleteEventHandler(OnSessionDeleteEvent, new Type[] { typeof(T) });
Type[] updateHandlers;
if (_affectedTypes != null)
{
updateHandlers = new Type[_affectedTypes.Length + 1];
if (_affectedTypes.Length > 0)
{
_affectedTypes.CopyTo(updateHandlers, 1);
}
updateHandlers[0] = typeof(T);
}
else
{
updateHandlers = new Type[] { typeof(T) };
}
_session.AddUpdateEventHandler(OnSessionUpdateEvent, updateHandlers);
_eventHandlersRegistered = true;
}
}
private void UnregisterEventHandlers()
{
if (_eventHandlersRegistered)
{
_session.RemoveInsertEventHandler(OnSessionInsertEvent);
_session.RemoveUpdateEventHandler(OnSessionUpdateEvent);
_session.RemoveDeleteEventHandler(OnSessionDeleteEvent);
_eventHandlersRegistered = false;
}
}
private void FireReset()
{
if (ListChanged != null)
ListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, -1));
}
public Session Session
{
get
{
return _session;
}
}
#region IBindingList Members
void IBindingList.AddIndex(PropertyDescriptor property)
{
throw new Exception("The method or operation is not implemented.");
}
object IBindingList.AddNew()
{
throw new Exception("The method or operation is not implemented.");
}
bool IBindingList.AllowEdit
{
get
{
return true;
}
}
bool IBindingList.AllowNew
{
get
{
return false;
}
}
bool IBindingList.AllowRemove
{
get
{
return false;
}
}
void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)
{
throw new Exception("The method or operation is not implemented.");
}
int IBindingList.Find(PropertyDescriptor property, object key)
{
throw new Exception("The method or operation is not implemented.");
}
bool IBindingList.IsSorted
{
get
{
return false;
}
}
private event ListChangedEventHandler ListChanged;
event ListChangedEventHandler IBindingList.ListChanged
{
add
{
ListChanged += value;
}
remove
{
ListChanged -= value;
}
}
void IBindingList.RemoveIndex(PropertyDescriptor property)
{
throw new Exception("The method or operation is not implemented.");
}
void IBindingList.RemoveSort()
{
throw new Exception("The method or operation is not implemented.");
}
ListSortDirection IBindingList.SortDirection
{
get { throw new Exception("The method or operation is not implemented."); }
}
PropertyDescriptor IBindingList.SortProperty
{
get { throw new Exception("The method or operation is not implemented."); }
}
bool IBindingList.SupportsChangeNotification
{
get
{
return true;
}
}
bool IBindingList.SupportsSearching
{
get
{
return false;
}
}
bool IBindingList.SupportsSorting
{
get
{
return false;
}
}
#endregion
#region IList Members
int System.Collections.IList.Add(object value)
{
throw new Exception("The method or operation is not implemented.");
}
void System.Collections.IList.Clear()
{
throw new Exception("The method or operation is not implemented.");
}
bool System.Collections.IList.Contains(object value)
{
return _rows.Contains((BoundDataGridViewRow<T>) value);
}
int System.Collections.IList.IndexOf(object value)
{
return _rows.IndexOf((BoundDataGridViewRow<T>)value);
}
void System.Collections.IList.Insert(int index, object value)
{
throw new Exception("The method or operation is not implemented.");
}
bool System.Collections.IList.IsFixedSize
{
get
{
return false;
}
}
bool System.Collections.IList.IsReadOnly
{
get
{
return false;
}
}
void System.Collections.IList.Remove(object value)
{
throw new Exception("The method or operation is not implemented.");
}
void System.Collections.IList.RemoveAt(int index)
{
throw new Exception("The method or operation is not implemented.");
}
object System.Collections.IList.this[int index]
{
get
{
return _rows[index];
}
set
{
throw new Exception("The method or operation is not implemented.");
}
}
#endregion
#region ICollection Members
void System.Collections.ICollection.CopyTo(Array array, int index)
{
throw new Exception("The method or operation is not implemented.");
}
int System.Collections.ICollection.Count
{
get
{
return _rows.Count;
}
}
bool System.Collections.ICollection.IsSynchronized
{
get
{
return false;
}
}
object System.Collections.ICollection.SyncRoot
{
get { throw new Exception("The method or operation is not implemented."); }
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _rows.GetEnumerator();
}
#endregion
public void Clear()
{
_rows.Clear();
UnregisterEventHandlers();
FireReset();
}
public void LoadSingle(T singleIndividual)
{
if (singleIndividual == null)
throw new ArgumentNullException("singleIndividual");
List<BoundDataGridViewRow<T>> oldRows = _rows;
string oldFilter = _filter;
try
{
_rows = new List<BoundDataGridViewRow<T>>();
_rows.Clear();
_rows.Add(new BoundDataGridViewRow<T>(singleIndividual, _columns));
_filter = "Identity = '" + singleIndividual.Identity.ToString() + "'";
RegisterEventHandlers();
FireReset();
}
catch (Exception)
{
_rows = oldRows;
_filter = oldFilter;
throw;
}
}
}
}
|