762 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			762 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.ComponentModel;
 | |
| using System.Collections.Generic;
 | |
| using System.Runtime.Serialization;
 | |
| using Csla.Properties;
 | |
| 
 | |
| namespace Csla
 | |
| {
 | |
|   /// <summary>
 | |
|   /// This is the base class from which most business collections
 | |
|   /// or lists will be derived.
 | |
|   /// </summary>
 | |
|   /// <typeparam name="T">Type of the business object being defined.</typeparam>
 | |
|   /// <typeparam name="C">Type of the child objects contained in the list.</typeparam>
 | |
|   [System.Diagnostics.CodeAnalysis.SuppressMessage(
 | |
|     "Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
 | |
|   [Serializable()]
 | |
|   public abstract class BusinessListBase<T, C> :
 | |
|       Core.ExtendedBindingList<C>,
 | |
|       Core.IEditableCollection, ICloneable, Core.ISavable, Core.IParent
 | |
|     where T : BusinessListBase<T, C>
 | |
|     where C : Core.IEditableBusinessObject
 | |
|   {
 | |
| 
 | |
|     #region Constructors
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Creates an instance of the object.
 | |
|     /// </summary>
 | |
|     protected BusinessListBase()
 | |
|     {
 | |
|       Initialize();
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region Initialize
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Override this method to set up event handlers so user
 | |
|     /// code in a partial class can respond to events raised by
 | |
|     /// generated code.
 | |
|     /// </summary>
 | |
|     protected virtual void Initialize()
 | |
|     { /* allows subclass to initialize events before any other activity occurs */ }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region IsDirty, IsValid
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Gets a value indicating whether this object's data has been changed.
 | |
|     /// </summary>
 | |
|     public bool IsDirty
 | |
|     {
 | |
|       get
 | |
|       {
 | |
|         // any non-new deletions make us dirty
 | |
|         foreach (C item in DeletedList)
 | |
|           if (!item.IsNew)
 | |
|             return true;
 | |
| 
 | |
|         // run through all the child objects
 | |
|         // and if any are dirty then then
 | |
|         // collection is dirty
 | |
|         foreach (C child in this)
 | |
|           if (child.IsDirty)
 | |
|             return true;
 | |
|         return false;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Gets a value indicating whether this object is currently in
 | |
|     /// a valid state (has no broken validation rules).
 | |
|     /// </summary>
 | |
|     public virtual bool IsValid
 | |
|     {
 | |
|       get
 | |
|       {
 | |
|         // run through all the child objects
 | |
|         // and if any are invalid then the
 | |
|         // collection is invalid
 | |
|         foreach (C child in this)
 | |
|           if (!child.IsValid)
 | |
|             return false;
 | |
|         return true;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region Begin/Cancel/ApplyEdit
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Starts a nested edit on the object.
 | |
|     /// </summary>
 | |
|     /// <remarks>
 | |
|     /// <para>
 | |
|     /// When this method is called the object takes a snapshot of
 | |
|     /// its current state (the values of its variables). This snapshot
 | |
|     /// can be restored by calling <see cref="CancelEdit" />
 | |
|     /// or committed by calling <see cref="ApplyEdit" />.
 | |
|     /// </para><para>
 | |
|     /// This is a nested operation. Each call to BeginEdit adds a new
 | |
|     /// snapshot of the object's state to a stack. You should ensure that 
 | |
|     /// for each call to BeginEdit there is a corresponding call to either 
 | |
|     /// CancelEdit or ApplyEdit to remove that snapshot from the stack.
 | |
|     /// </para><para>
 | |
|     /// See Chapters 2 and 3 for details on n-level undo and state stacking.
 | |
|     /// </para><para>
 | |
|     /// This method triggers the copying of all child object states.
 | |
|     /// </para>
 | |
|     /// </remarks>
 | |
|     public void BeginEdit()
 | |
|     {
 | |
|       if (this.IsChild)
 | |
|         throw new NotSupportedException(Resources.NoBeginEditChildException);
 | |
| 
 | |
|       CopyState();
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Cancels the current edit process, restoring the object's state to
 | |
|     /// its previous values.
 | |
|     /// </summary>
 | |
|     /// <remarks>
 | |
|     /// Calling this method causes the most recently taken snapshot of the 
 | |
|     /// object's state to be restored. This resets the object's values
 | |
|     /// to the point of the last <see cref="BeginEdit" />
 | |
|     /// call.
 | |
|     /// <para>
 | |
|     /// This method triggers an undo in all child objects.
 | |
|     /// </para>
 | |
|     /// </remarks>
 | |
|     public void CancelEdit()
 | |
|     {
 | |
|       if (this.IsChild)
 | |
|         throw new NotSupportedException(Resources.NoCancelEditChildException);
 | |
| 
 | |
|       UndoChanges();
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Commits the current edit process.
 | |
|     /// </summary>
 | |
|     /// <remarks>
 | |
|     /// Calling this method causes the most recently taken snapshot of the 
 | |
|     /// object's state to be discarded, thus committing any changes made
 | |
|     /// to the object's state since the last 
 | |
|     /// <see cref="BeginEdit" /> call.
 | |
|     /// <para>
 | |
|     /// This method triggers an <see cref="Core.BusinessBase.ApplyEdit"/>
 | |
|     ///  in all child objects.
 | |
|     /// </para>
 | |
|     /// </remarks>
 | |
|     public void ApplyEdit()
 | |
|     {
 | |
|       if (this.IsChild)
 | |
|         throw new NotSupportedException(Resources.NoApplyEditChildException);
 | |
| 
 | |
|       AcceptChanges();
 | |
|     }
 | |
| 
 | |
|     void Core.IParent.ApplyEditChild(Core.IEditableBusinessObject child)
 | |
|     {
 | |
|       EditChildComplete(child);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Override this method to be notified when a child object's
 | |
|     /// <see cref="Core.BusinessBase.ApplyEdit" /> method has
 | |
|     /// completed.
 | |
|     /// </summary>
 | |
|     /// <param name="child">The child object that was edited.</param>
 | |
|     protected virtual void EditChildComplete(Core.IEditableBusinessObject child)
 | |
|     {
 | |
| 
 | |
|       // do nothing, we don't really care
 | |
|       // when a child has its edits applied
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region N-level undo
 | |
| 
 | |
|     void Core.IUndoableObject.CopyState()
 | |
|     {
 | |
|       CopyState();
 | |
|     }
 | |
| 
 | |
|     void Core.IUndoableObject.UndoChanges()
 | |
|     {
 | |
|       UndoChanges();
 | |
|     }
 | |
| 
 | |
|     void Core.IUndoableObject.AcceptChanges()
 | |
|     {
 | |
|       AcceptChanges();
 | |
|     }
 | |
| 
 | |
|     private void CopyState()
 | |
|     {
 | |
|       // we are going a level deeper in editing
 | |
|       _editLevel += 1;
 | |
| 
 | |
|       // cascade the call to all child objects
 | |
|       foreach (C child in this)
 | |
|         child.CopyState();
 | |
| 
 | |
|       // cascade the call to all deleted child objects
 | |
|       foreach (C child in DeletedList)
 | |
|         child.CopyState();
 | |
|     }
 | |
| 
 | |
|     private void UndoChanges()
 | |
|     {
 | |
|       C child;
 | |
| 
 | |
|       // we are coming up one edit level
 | |
|       _editLevel -= 1;
 | |
|       if (_editLevel < 0) _editLevel = 0;
 | |
| 
 | |
|       // Cancel edit on all current items
 | |
|       for (int index = Count - 1; index >= 0; index--)
 | |
|       {
 | |
|         child = this[index];
 | |
|         child.UndoChanges();
 | |
|         // if item is below its point of addition, remove
 | |
|         if (child.EditLevelAdded > _editLevel)
 | |
|         {
 | |
|           bool oldAllowRemove = this.AllowRemove;
 | |
|           try
 | |
|           {
 | |
|             this.AllowRemove = true;
 | |
|             RemoveAt(index);
 | |
|           }
 | |
|           finally
 | |
|           {
 | |
|             this.AllowRemove = oldAllowRemove;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       // cancel edit on all deleted items
 | |
|       for (int index = DeletedList.Count - 1; index >= 0; index--)
 | |
|       {
 | |
|         child = DeletedList[index];
 | |
|         child.UndoChanges();
 | |
|         if (child.EditLevelAdded > _editLevel)
 | |
|         {
 | |
|           // if item is below its point of addition, remove
 | |
|           DeletedList.RemoveAt(index);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           // if item is no longer deleted move back to main list
 | |
|           if (!child.IsDeleted) UnDeleteChild(child);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     private void AcceptChanges()
 | |
|     {
 | |
|       // we are coming up one edit level
 | |
|       _editLevel -= 1;
 | |
|       if (_editLevel < 0) _editLevel = 0;
 | |
| 
 | |
|       // cascade the call to all child objects
 | |
|       foreach (C child in this)
 | |
|       {
 | |
|         child.AcceptChanges();
 | |
|         // if item is below its point of addition, lower point of addition
 | |
|         if (child.EditLevelAdded > _editLevel) child.EditLevelAdded = _editLevel;
 | |
|       }
 | |
| 
 | |
|       // cascade the call to all deleted child objects
 | |
|       for (int index = DeletedList.Count - 1; index >= 0; index--)
 | |
|       {
 | |
|         C child = DeletedList[index];
 | |
|         child.AcceptChanges();
 | |
|         // if item is below its point of addition, remove
 | |
|         if (child.EditLevelAdded > _editLevel)
 | |
|           DeletedList.RemoveAt(index);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region Delete and Undelete child
 | |
| 
 | |
|     private List<C> _deletedList;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// A collection containing all child objects marked
 | |
|     /// for deletion.
 | |
|     /// </summary>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage(
 | |
|       "Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
 | |
|     [EditorBrowsable(EditorBrowsableState.Advanced)]
 | |
|     protected List<C> DeletedList
 | |
|     {
 | |
|       get 
 | |
|       { 
 | |
|         if (_deletedList == null)
 | |
|           _deletedList = new List<C>();
 | |
|         return _deletedList; 
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     private void DeleteChild(C child)
 | |
|     {
 | |
|       // mark the object as deleted
 | |
|       child.DeleteChild();
 | |
|       // and add it to the deleted collection for storage
 | |
|       DeletedList.Add(child);
 | |
|     }
 | |
| 
 | |
|     private void UnDeleteChild(C child)
 | |
|     {
 | |
|       // we are inserting an _existing_ object so
 | |
|       // we need to preserve the object's editleveladded value
 | |
|       // because it will be changed by the normal add process
 | |
|       int saveLevel = child.EditLevelAdded;
 | |
|       Add(child);
 | |
|       child.EditLevelAdded = saveLevel;
 | |
| 
 | |
|       // since the object is no longer deleted, remove it from
 | |
|       // the deleted collection
 | |
|       DeletedList.Remove(child);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Returns <see langword="true"/> if the internal deleted list
 | |
|     /// contains the specified child object.
 | |
|     /// </summary>
 | |
|     /// <param name="item">Child object to check.</param>
 | |
|     [EditorBrowsable(EditorBrowsableState.Advanced)]
 | |
|     public bool ContainsDeleted(C item)
 | |
|     {
 | |
|       return DeletedList.Contains(item);
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region Insert, Remove, Clear
 | |
| 
 | |
|     /// <summary>
 | |
|     /// This method is called by a child object when it
 | |
|     /// wants to be removed from the collection.
 | |
|     /// </summary>
 | |
|     /// <param name="child">The child object to remove.</param>
 | |
|     void Core.IEditableCollection.RemoveChild(Csla.Core.IEditableBusinessObject child)
 | |
|     {
 | |
|       Remove((C)child);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// This method is called by a child object when it
 | |
|     /// wants to be removed from the collection.
 | |
|     /// </summary>
 | |
|     /// <param name="child">The child object to remove.</param>
 | |
|     void Core.IParent.RemoveChild(Csla.Core.IEditableBusinessObject child)
 | |
|     {
 | |
|       Remove((C)child);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Sets the edit level of the child object as it is added.
 | |
|     /// </summary>
 | |
|     /// <param name="index">Index of the item to insert.</param>
 | |
|     /// <param name="item">Item to insert.</param>
 | |
|     protected override void InsertItem(int index, C item)
 | |
|     {
 | |
|       // when an object is inserted we assume it is
 | |
|       // a new object and so the edit level when it was
 | |
|       // added must be set
 | |
|       item.EditLevelAdded = _editLevel;
 | |
|       item.SetParent(this);
 | |
|       base.InsertItem(index, item);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Marks the child object for deletion and moves it to
 | |
|     /// the collection of deleted objects.
 | |
|     /// </summary>
 | |
|     /// <param name="index">Index of the item to remove.</param>
 | |
|     protected override void RemoveItem(int index)
 | |
|     {
 | |
|       // when an object is 'removed' it is really
 | |
|       // being deleted, so do the deletion work
 | |
|       C child = this[index];
 | |
|       base.RemoveItem(index);
 | |
|       CopyToDeletedList(child);
 | |
|     }
 | |
| 
 | |
|     private void CopyToDeletedList(C child)
 | |
|     {
 | |
|       DeleteChild(child);
 | |
|       INotifyPropertyChanged c = child as INotifyPropertyChanged;
 | |
|       if (c != null)
 | |
|         c.PropertyChanged -= new PropertyChangedEventHandler(Child_PropertyChanged);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Clears the collection, moving all active
 | |
|     /// items to the deleted list.
 | |
|     /// </summary>
 | |
|     protected override void ClearItems()
 | |
|     {
 | |
|       while (base.Count > 0) RemoveItem(0);
 | |
|       base.ClearItems();
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Replaces the item at the specified index with
 | |
|     /// the specified item, first moving the original
 | |
|     /// item to the deleted list.
 | |
|     /// </summary>
 | |
|     /// <param name="index">The zero-based index of the item to replace.</param>
 | |
|     /// <param name="item">
 | |
|     /// The new value for the item at the specified index. 
 | |
|     /// The value can be null for reference types.
 | |
|     /// </param>
 | |
|     /// <remarks></remarks>
 | |
|     protected override void SetItem(int index, C item)
 | |
|     {
 | |
|       // copy the original object to the deleted list,
 | |
|       // marking as deleted, etc.
 | |
|       C child = default(C);
 | |
|       if (!ReferenceEquals(this[index], item))
 | |
|         child = this[index];
 | |
|       // replace the original object with this new
 | |
|       // object
 | |
|       base.SetItem(index, item);
 | |
|       if (child != null)
 | |
|         CopyToDeletedList(child);
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region Edit level tracking
 | |
| 
 | |
|     // keep track of how many edit levels we have
 | |
|     private int _editLevel;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Returns the current edit level of the object.
 | |
|     /// </summary>
 | |
|     [EditorBrowsable(EditorBrowsableState.Never)]
 | |
|     protected int EditLevel
 | |
|     {
 | |
|       get { return _editLevel; }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region IsChild
 | |
| 
 | |
|     [NotUndoable()]
 | |
|     private bool _isChild = false;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Indicates whether this collection object is a child object.
 | |
|     /// </summary>
 | |
|     /// <returns>True if this is a child object.</returns>
 | |
|     protected bool IsChild
 | |
|     {
 | |
|       get { return _isChild; }
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Marks the object as being a child object.
 | |
|     /// </summary>
 | |
|     /// <remarks>
 | |
|     /// <para>
 | |
|     /// By default all business objects are 'parent' objects. This means
 | |
|     /// that they can be directly retrieved and updated into the database.
 | |
|     /// </para><para>
 | |
|     /// We often also need child objects. These are objects which are contained
 | |
|     /// within other objects. For instance, a parent Invoice object will contain
 | |
|     /// child LineItem objects.
 | |
|     /// </para><para>
 | |
|     /// To create a child object, the MarkAsChild method must be called as the
 | |
|     /// object is created. Please see Chapter 7 for details on the use of the
 | |
|     /// MarkAsChild method.
 | |
|     /// </para>
 | |
|     /// </remarks>
 | |
|     protected void MarkAsChild()
 | |
|     {
 | |
|       _isChild = true;
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region ICloneable
 | |
| 
 | |
|     object ICloneable.Clone()
 | |
|     {
 | |
|       return GetClone();
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Creates a clone of the object.
 | |
|     /// </summary>
 | |
|     /// <returns>A new object containing the exact data of the original object.</returns>
 | |
|     [EditorBrowsable(EditorBrowsableState.Advanced)]
 | |
|     protected virtual object GetClone()
 | |
|     {
 | |
|       return Core.ObjectCloner.Clone(this);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Creates a clone of the object.
 | |
|     /// </summary>
 | |
|     /// <returns>A new object containing the exact data of the original object.</returns>
 | |
|     public T Clone()
 | |
|     {
 | |
|       return (T)GetClone();
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region Cascade Child events
 | |
| 
 | |
|     private void Child_PropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|     {
 | |
|       for (int index = 0; index < Count; index++)
 | |
|       {
 | |
|         if (ReferenceEquals(this[index], sender))
 | |
|         {
 | |
|           OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index));
 | |
|           return;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region Serialization Notification
 | |
| 
 | |
|     [OnDeserialized()]
 | |
|     private void OnDeserializedHandler(StreamingContext context)
 | |
|     {
 | |
|       OnDeserialized(context);
 | |
|       foreach (Core.IEditableBusinessObject child in this)
 | |
|       {
 | |
|         child.SetParent(this);
 | |
|         INotifyPropertyChanged c = child as INotifyPropertyChanged;
 | |
|         if (c != null)
 | |
|           c.PropertyChanged += new PropertyChangedEventHandler(Child_PropertyChanged);
 | |
|       }
 | |
|       foreach (Core.IEditableBusinessObject child in DeletedList)
 | |
|         child.SetParent(this);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// This method is called on a newly deserialized object
 | |
|     /// after deserialization is complete.
 | |
|     /// </summary>
 | |
|     [EditorBrowsable(EditorBrowsableState.Advanced)]
 | |
|     protected virtual void OnDeserialized(StreamingContext context)
 | |
|     {
 | |
|       // do nothing - this is here so a subclass
 | |
|       // could override if needed
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region Data Access
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Saves the object to the database.
 | |
|     /// </summary>
 | |
|     /// <remarks>
 | |
|     /// <para>
 | |
|     /// Calling this method starts the save operation, causing the all child
 | |
|     /// objects to be inserted, updated or deleted within the database based on the
 | |
|     /// each object's current state.
 | |
|     /// </para><para>
 | |
|     /// All this is contingent on <see cref="IsDirty" />. If
 | |
|     /// this value is <see langword="false"/>, no data operation occurs. 
 | |
|     /// It is also contingent on <see cref="IsValid" />. If this value is 
 | |
|     /// <see langword="false"/> an exception will be thrown to 
 | |
|     /// indicate that the UI attempted to save an invalid object.
 | |
|     /// </para><para>
 | |
|     /// It is important to note that this method returns a new version of the
 | |
|     /// business collection that contains any data updated during the save operation.
 | |
|     /// You MUST update all object references to use this new version of the
 | |
|     /// business collection in order to have access to the correct object data.
 | |
|     /// </para><para>
 | |
|     /// You can override this method to add your own custom behaviors to the save
 | |
|     /// operation. For instance, you may add some security checks to make sure
 | |
|     /// the user can save the object. If all security checks pass, you would then
 | |
|     /// invoke the base Save method via <c>MyBase.Save()</c>.
 | |
|     /// </para>
 | |
|     /// </remarks>
 | |
|     /// <returns>A new object containing the saved values.</returns>
 | |
|     public virtual T Save()
 | |
|     {
 | |
|       T result;
 | |
|       if (this.IsChild)
 | |
|         throw new NotSupportedException(Resources.NoSaveChildException);
 | |
| 
 | |
|       if (_editLevel > 0)
 | |
|         throw new Validation.ValidationException(Resources.NoSaveEditingException);
 | |
| 
 | |
|       if (!IsValid)
 | |
|         throw new Validation.ValidationException(Resources.NoSaveInvalidException);
 | |
| 
 | |
|       if (IsDirty)
 | |
|         result = (T)DataPortal.Update(this);
 | |
|       else
 | |
|         result = (T)this;
 | |
|       OnSaved(result);
 | |
|       return result;
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Override this method to load a new business object with default
 | |
|     /// values from the database.
 | |
|     /// </summary>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
 | |
|     protected virtual void DataPortal_Create()
 | |
|     {
 | |
|       throw new NotSupportedException(Resources.CreateNotSupportedException);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Override this method to allow retrieval of an existing business
 | |
|     /// object based on data in the database.
 | |
|     /// </summary>
 | |
|     /// <param name="criteria">An object containing criteria values to identify the object.</param>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
 | |
|     protected virtual void DataPortal_Fetch(object criteria)
 | |
|     {
 | |
|       throw new NotSupportedException(Resources.FetchNotSupportedException);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Override this method to allow update of a business
 | |
|     /// object.
 | |
|     /// </summary>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
 | |
|     protected virtual void DataPortal_Update()
 | |
|     {
 | |
|       throw new NotSupportedException(Resources.UpdateNotSupportedException);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Override this method to allow immediate deletion of a business object.
 | |
|     /// </summary>
 | |
|     /// <param name="criteria">An object containing criteria values to identify the object.</param>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
 | |
|     protected virtual void DataPortal_Delete(object criteria)
 | |
|     {
 | |
|       throw new NotSupportedException(Resources.DeleteNotSupportedException);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Called by the server-side DataPortal prior to calling the 
 | |
|     /// requested DataPortal_xyz method.
 | |
|     /// </summary>
 | |
|     /// <param name="e">The DataPortalContext object passed to the DataPortal.</param>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
 | |
|     [EditorBrowsable(EditorBrowsableState.Advanced)]
 | |
|     protected virtual void DataPortal_OnDataPortalInvoke(DataPortalEventArgs e)
 | |
|     {
 | |
| 
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Called by the server-side DataPortal after calling the 
 | |
|     /// requested DataPortal_xyz method.
 | |
|     /// </summary>
 | |
|     /// <param name="e">The DataPortalContext object passed to the DataPortal.</param>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
 | |
|     [EditorBrowsable(EditorBrowsableState.Advanced)]
 | |
|     protected virtual void DataPortal_OnDataPortalInvokeComplete(DataPortalEventArgs e)
 | |
|     {
 | |
| 
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Called by the server-side DataPortal if an exception
 | |
|     /// occurs during data access.
 | |
|     /// </summary>
 | |
|     /// <param name="e">The DataPortalContext object passed to the DataPortal.</param>
 | |
|     /// <param name="ex">The Exception thrown during data access.</param>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", MessageId = "Member")]
 | |
|     [EditorBrowsable(EditorBrowsableState.Advanced)]
 | |
|     protected virtual void DataPortal_OnDataPortalException(DataPortalEventArgs e, Exception ex)
 | |
|     {
 | |
| 
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|     #region ISavable Members
 | |
| 
 | |
|     object Csla.Core.ISavable.Save()
 | |
|     {
 | |
|       return Save();
 | |
|     }
 | |
| 
 | |
|     [NonSerialized()]
 | |
|     [NotUndoable]
 | |
|     private EventHandler<Csla.Core.SavedEventArgs> _nonSerializableSavedHandlers;
 | |
|     [NotUndoable]
 | |
|     private EventHandler<Csla.Core.SavedEventArgs> _serializableSavedHandlers;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Event raised when an object has been saved.
 | |
|     /// </summary>
 | |
|     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design",
 | |
|       "CA1062:ValidateArgumentsOfPublicMethods")]
 | |
|     public event EventHandler<Csla.Core.SavedEventArgs> Saved
 | |
|     {
 | |
|       add
 | |
|       {
 | |
|         if (value.Method.IsPublic &&
 | |
|            (value.Method.DeclaringType.IsSerializable ||
 | |
|             value.Method.IsStatic))
 | |
|           _serializableSavedHandlers = (EventHandler<Csla.Core.SavedEventArgs>)
 | |
|             System.Delegate.Combine(_serializableSavedHandlers, value);
 | |
|         else
 | |
|           _nonSerializableSavedHandlers = (EventHandler<Csla.Core.SavedEventArgs>)
 | |
|             System.Delegate.Combine(_nonSerializableSavedHandlers, value);
 | |
|       }
 | |
|       remove
 | |
|       {
 | |
|         if (value.Method.IsPublic &&
 | |
|            (value.Method.DeclaringType.IsSerializable ||
 | |
|             value.Method.IsStatic))
 | |
|           _serializableSavedHandlers = (EventHandler<Csla.Core.SavedEventArgs>)
 | |
|             System.Delegate.Remove(_serializableSavedHandlers, value);
 | |
|         else
 | |
|           _nonSerializableSavedHandlers = (EventHandler<Csla.Core.SavedEventArgs>)
 | |
|             System.Delegate.Remove(_nonSerializableSavedHandlers, value);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Raises the <see cref="Saved"/> event, indicating that the
 | |
|     /// object has been saved, and providing a reference
 | |
|     /// to the new object instance.
 | |
|     /// </summary>
 | |
|     /// <param name="newObject">The new object instance.</param>
 | |
|     [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Advanced)]
 | |
|     protected void OnSaved(T newObject)
 | |
|     {
 | |
|       Csla.Core.SavedEventArgs args = new Csla.Core.SavedEventArgs(newObject);
 | |
|       if (_nonSerializableSavedHandlers != null)
 | |
|         _nonSerializableSavedHandlers.Invoke(this, args);
 | |
|       if (_serializableSavedHandlers != null)
 | |
|         _serializableSavedHandlers.Invoke(this, args);
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| 
 | |
|   }
 | |
| } |