CollectionViewProxy.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / Data / CollectionViewProxy.cs / 1305600 / CollectionViewProxy.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// See spec at http://avalon/connecteddata/Specs/CollectionView.mht 
// 
// Description: Proxy that adds context affinity to an ICollectionView that
//              doesn't already have it. 
//
//---------------------------------------------------------------------------

using System; 
using System.Collections;
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Collections.Specialized;
using System.ComponentModel; 
using System.Threading;
using System.Windows;
using System.Windows.Data;
 
namespace MS.Internal.Data
{ 
 
    ///
    /// Proxy view, used to interpose between the UI and a view that doesn't 
    /// support context affinity.
    ///
    internal class CollectionViewProxy : CollectionView, IEditableCollectionViewAddNewItem, IItemProperties
    { 
        //-----------------------------------------------------
        // 
        //  Constructors 
        //
        //----------------------------------------------------- 

        internal CollectionViewProxy(ICollectionView view)
            : base(view.SourceCollection, false)
        { 
            _view = view;
 
            view.CollectionChanged += new NotifyCollectionChangedEventHandler(_OnViewChanged); 

            view.CurrentChanging += new CurrentChangingEventHandler(_OnCurrentChanging); 
            view.CurrentChanged += new EventHandler(_OnCurrentChanged);

            INotifyPropertyChanged ipc = view as INotifyPropertyChanged;
            if (ipc != null) 
                ipc.PropertyChanged += new PropertyChangedEventHandler(_OnPropertyChanged);
        } 
 

        //------------------------------------------------------ 
        //
        //  Interfaces
        //
        //----------------------------------------------------- 

        #region ICollectionView 
 
        /// 
        /// Culture to use during sorting. 
        /// 
        public override System.Globalization.CultureInfo Culture
        {
            get { return ProxiedView.Culture; } 
            set { ProxiedView.Culture = value; }
        } 
 
        /// 
        /// Return true if the item belongs to this view.  No assumptions are 
        /// made about the item. This method will behave similarly to IList.Contains().
        /// If the caller knows that the item belongs to the
        /// underlying collection, it is more efficient to call PassesFilter.
        ///  
        public override bool Contains(object item)
        { 
            return ProxiedView.Contains(item); 
        }
 
        /// 
        /// SourceCollection is the original un-filtered collection of which
        /// this ICollectionView is a view.
        ///  
        public override IEnumerable SourceCollection
        { 
            get { return base.SourceCollection; } 
        }
 
        /// 
        /// Set/get a filter callback to filter out items in collection.
        /// This property will always accept a filter, but the collection view for the
        /// underlying InnerList or ItemsSource may not actually support filtering. 
        /// Please check 
        ///  
        ///  
        /// Collections assigned to ItemsSource may not support filtering and could throw a NotSupportedException.
        /// Use  property to test if sorting is supported before adding 
        /// to SortDescriptions.
        /// 
        public override Predicate Filter
        { 
            get { return ProxiedView.Filter; }
            set { ProxiedView.Filter = value; } 
        } 

        ///  
        /// Test if this ICollectionView supports filtering before assigning
        /// a filter callback to .
        /// 
        public override bool CanFilter 
        {
            get { return ProxiedView.CanFilter; } 
        } 

        ///  
        /// Set/get Sort criteria to sort items in collection.
        /// 
        /// 
        /// 

/// Clear a sort criteria by assigning SortDescription.Empty to this property. /// One or more sort criteria in form of /// can be used, each specifying a property and direction to sort by. ///

///
/// /// Simpler implementations do not support sorting and will throw a NotSupportedException. /// Use property to test if sorting is supported before adding /// to SortDescriptions. /// public override SortDescriptionCollection SortDescriptions { get { return ProxiedView.SortDescriptions; } } /// /// Test if this ICollectionView supports sorting before adding /// to . /// public override bool CanSort { get { return ProxiedView.CanSort; } } /// /// Returns true if this view really supports grouping. /// When this returns false, the rest of the interface is ignored. /// public override bool CanGroup { get { return ProxiedView.CanGroup; } } /// /// The description of grouping, indexed by level. /// public override ObservableCollection GroupDescriptions { get { return ProxiedView.GroupDescriptions; } } /// /// The top-level groups, constructed according to the descriptions /// given in GroupDescriptions. /// public override ReadOnlyObservableCollection Groups { get { return ProxiedView.Groups; } } /// Re-create the view, using any . public override void Refresh() { IndexedEnumerable indexer = (IndexedEnumerable) Interlocked.Exchange(ref _indexer, null); if (indexer != null) { indexer.Invalidate(); } ProxiedView.Refresh(); } /// /// Enter a Defer Cycle. /// Defer cycles are used to coalesce changes to the ICollectionView. /// public override IDisposable DeferRefresh() { return ProxiedView.DeferRefresh(); } /// Return current item. public override object CurrentItem { get { return ProxiedView.CurrentItem; } } /// /// The ordinal position of the within the (optionally /// sorted and filtered) view. /// public override int CurrentPosition { get { return ProxiedView.CurrentPosition; } } /// Return true if currency is beyond the end (End-Of-File). public override bool IsCurrentAfterLast { get { return ProxiedView.IsCurrentAfterLast; } } /// Return true if currency is before the beginning (Beginning-Of-File). public override bool IsCurrentBeforeFirst { get { return ProxiedView.IsCurrentBeforeFirst; } } /// Move to the first item. public override bool MoveCurrentToFirst() { return ProxiedView.MoveCurrentToFirst(); } /// Move to the previous item. public override bool MoveCurrentToPrevious() { return ProxiedView.MoveCurrentToPrevious(); } /// Move to the next item. public override bool MoveCurrentToNext() { return ProxiedView.MoveCurrentToNext(); } /// Move to the last item. public override bool MoveCurrentToLast() { return ProxiedView.MoveCurrentToLast(); } /// Move to the given item. public override bool MoveCurrentTo(object item) { return ProxiedView.MoveCurrentTo(item); } /// Move CurrentItem to this index public override bool MoveCurrentToPosition(int position) { // // If the index is out of range here, I'll let the // ProxiedView be the one to make that determination. // return ProxiedView.MoveCurrentToPosition(position); } public override event CurrentChangingEventHandler CurrentChanging { add { PrivateCurrentChanging += value; } remove { PrivateCurrentChanging -= value; } } public override event EventHandler CurrentChanged { add { PrivateCurrentChanged += value; } remove { PrivateCurrentChanged -= value; } } #endregion ICollectionView //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties /// /// Return the number of records (or -1, meaning "don't know"). /// A virtualizing view should return the best estimate it can /// without de-virtualizing all the data. A non-virtualizing view /// should return the exact count of its (filtered) data. /// public override int Count { get { return EnumerableWrapper.Count; } } public override bool IsEmpty { get { return ProxiedView.IsEmpty; } } public ICollectionView ProxiedView { get { // VerifyAccess(); return _view; } } #endregion Public Properties //----------------------------------------------------- // // Public Methods // //------------------------------------------------------ #region Public Methods /// Return the index where the given de belongs, or -1 if this index is unknown. /// More precisely, if this returns an index other than -1, it must always be true that /// view[index-1] < de <= view[index], where the comparisons are done via /// the view's IComparer.Compare method (if any). /// /// data item public override int IndexOf(object item) { return EnumerableWrapper.IndexOf(item); } /// /// Return true if the item belongs to this view. The item is assumed to belong to the /// underlying DataCollection; this method merely takes filters into account. /// It is commonly used during collection-changed notifications to determine if the added/removed /// item requires processing. /// Returns true if no filter is set on collection view. /// public override bool PassesFilter(object item) { if (ProxiedView.CanFilter && ProxiedView.Filter != null && item != NewItemPlaceholder && item != ((IEditableCollectionView)this).CurrentAddItem) return ProxiedView.Filter(item); return true; } /// /// Retrieve item at the given zero-based index in this CollectionView. /// /// /// Thrown if index is out of range /// public override object GetItemAt(int index) { // only check lower bound because Count could be expensive if (index < 0) throw new ArgumentOutOfRangeException("index"); return EnumerableWrapper[index]; } #endregion Public Methods #region IEditableCollectionView #region Adding new items /// /// Indicates whether to include a placeholder for a new item, and if so, /// where to put it. /// NewItemPlaceholderPosition IEditableCollectionView.NewItemPlaceholderPosition { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.NewItemPlaceholderPosition; } else { return NewItemPlaceholderPosition.None; } } set { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.NewItemPlaceholderPosition = value; } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "NewItemPlaceholderPosition")); } } } /// /// Return true if the view supports . /// bool IEditableCollectionView.CanAddNew { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CanAddNew; } else { return false; } } } /// /// Add a new item to the underlying collection. Returns the new item. /// After calling AddNew and changing the new item as desired, either /// or should be /// called to complete the transaction. /// object IEditableCollectionView.AddNew() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.AddNew(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "AddNew")); } } /// /// Complete the transaction started by . The new /// item remains in the collection, and the view's sort, filter, and grouping /// specifications (if any) are applied to the new item. /// void IEditableCollectionView.CommitNew() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.CommitNew(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "CommitNew")); } } /// /// Complete the transaction started by . The new /// item is removed from the collection. /// void IEditableCollectionView.CancelNew() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.CancelNew(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "CancelNew")); } } /// /// Returns true if an transaction is in progress. /// bool IEditableCollectionView.IsAddingNew { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.IsAddingNew; } else { return false; } } } /// /// When an transaction is in progress, this property /// returns the new item. Otherwise it returns null. /// object IEditableCollectionView.CurrentAddItem { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CurrentAddItem; } else { return null; } } } #endregion Adding new items #region Removing items /// /// Return true if the view supports and /// . /// bool IEditableCollectionView.CanRemove { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CanRemove; } else { return false; } } } /// /// Remove the item at the given index from the underlying collection. /// The index is interpreted with respect to the view (not with respect to /// the underlying collection). /// void IEditableCollectionView.RemoveAt(int index) { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.RemoveAt(index); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "RemoveAt")); } } /// /// Remove the given item from the underlying collection. /// void IEditableCollectionView.Remove(object item) { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.Remove(item); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "Remove")); } } #endregion Removing items #region Transactional editing of an item /// /// Begins an editing transaction on the given item. The transaction is /// completed by calling either or /// . Any changes made to the item during /// the transaction are considered "pending", provided that the view supports /// the notion of "pending changes" for the given item. /// void IEditableCollectionView.EditItem(object item) { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.EditItem(item); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "EditItem")); } } /// /// Complete the transaction started by . /// The pending changes (if any) to the item are committed. /// void IEditableCollectionView.CommitEdit() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.CommitEdit(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "CommitEdit")); } } /// /// Complete the transaction started by . /// The pending changes (if any) to the item are discarded. /// void IEditableCollectionView.CancelEdit() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.CancelEdit(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "CancelEdit")); } } /// /// Returns true if the view supports the notion of "pending changes" on the /// current edit item. This may vary, depending on the view and the particular /// item. For example, a view might return true if the current edit item /// implements , or if the view has special /// knowledge about the item that it can use to support rollback of pending /// changes. /// bool IEditableCollectionView.CanCancelEdit { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CanCancelEdit; } else { return false; } } } /// /// Returns true if an transaction is in progress. /// bool IEditableCollectionView.IsEditingItem { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.IsEditingItem; } else { return false; } } } /// /// When an transaction is in progress, this property /// returns the affected item. Otherwise it returns null. /// object IEditableCollectionView.CurrentEditItem { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CurrentEditItem; } else { return null; } } } #endregion Transactional editing of an item #endregion IEditableCollectionView #region IEditableCollectionViewAddNewItem /// /// Return true if the view supports . /// bool IEditableCollectionViewAddNewItem.CanAddNewItem { get { IEditableCollectionViewAddNewItem ani = ProxiedView as IEditableCollectionViewAddNewItem; if (ani != null) { return ani.CanAddNewItem; } else { return false; } } } /// /// Add a new item to the underlying collection. Returns the new item. /// After calling AddNewItem and changing the new item as desired, either /// or should be /// called to complete the transaction. /// object IEditableCollectionViewAddNewItem.AddNewItem(object newItem) { IEditableCollectionViewAddNewItem ani = ProxiedView as IEditableCollectionViewAddNewItem; if (ani != null) { return ani.AddNewItem(newItem); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "AddNewItem")); } } #endregion IEditableCollectionViewAddNewItem #region IItemProperties /// /// Returns information about the properties available on items in the /// underlying collection. This information may come from a schema, from /// a type descriptor, from a representative item, or from some other source /// known to the view. /// ReadOnlyCollection IItemProperties.ItemProperties { get { IItemProperties iip = ProxiedView as IItemProperties; if (iip != null) { return iip.ItemProperties; } else { return null; } } } #endregion IItemProperties //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods /// Implementation of IEnumerable.GetEnumerator(). /// This provides a way to enumerate the members of the collection /// without changing the currency. /// protected override IEnumerator GetEnumerator() { return ((IEnumerable) ProxiedView).GetEnumerator(); } #endregion Protected Methods //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods void _OnPropertyChanged(object sender, PropertyChangedEventArgs args) { OnPropertyChanged(args); } void _OnViewChanged(object sender, NotifyCollectionChangedEventArgs args) { // VerifyAccess(); // will throw an exception if caller is not in correct UiContext OnCollectionChanged(args); } void _OnCurrentChanging(object sender, CurrentChangingEventArgs args) { // VerifyAccess(); // will throw an exception if caller is not in correct UiContext if (PrivateCurrentChanging != null) PrivateCurrentChanging(this, args); } void _OnCurrentChanged(object sender, EventArgs args) { // VerifyAccess(); // will throw an exception if caller is not in correct UiContext if (PrivateCurrentChanged != null) PrivateCurrentChanged(this, args); } private IndexedEnumerable EnumerableWrapper { get { if (_indexer == null) { IndexedEnumerable newIndexer = new IndexedEnumerable(ProxiedView, new Predicate(this.PassesFilter)); Interlocked.CompareExchange(ref _indexer, newIndexer, null); } return _indexer; } } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ ICollectionView _view; IndexedEnumerable _indexer; event CurrentChangingEventHandler PrivateCurrentChanging; event EventHandler PrivateCurrentChanged; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // // Copyright (C) Microsoft Corporation. All rights reserved. // // // See spec at http://avalon/connecteddata/Specs/CollectionView.mht // // Description: Proxy that adds context affinity to an ICollectionView that // doesn't already have it. // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Threading; using System.Windows; using System.Windows.Data; namespace MS.Internal.Data { /// /// Proxy view, used to interpose between the UI and a view that doesn't /// support context affinity. /// internal class CollectionViewProxy : CollectionView, IEditableCollectionViewAddNewItem, IItemProperties { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- internal CollectionViewProxy(ICollectionView view) : base(view.SourceCollection, false) { _view = view; view.CollectionChanged += new NotifyCollectionChangedEventHandler(_OnViewChanged); view.CurrentChanging += new CurrentChangingEventHandler(_OnCurrentChanging); view.CurrentChanged += new EventHandler(_OnCurrentChanged); INotifyPropertyChanged ipc = view as INotifyPropertyChanged; if (ipc != null) ipc.PropertyChanged += new PropertyChangedEventHandler(_OnPropertyChanged); } //------------------------------------------------------ // // Interfaces // //----------------------------------------------------- #region ICollectionView /// /// Culture to use during sorting. /// public override System.Globalization.CultureInfo Culture { get { return ProxiedView.Culture; } set { ProxiedView.Culture = value; } } /// /// Return true if the item belongs to this view. No assumptions are /// made about the item. This method will behave similarly to IList.Contains(). /// If the caller knows that the item belongs to the /// underlying collection, it is more efficient to call PassesFilter. /// public override bool Contains(object item) { return ProxiedView.Contains(item); } /// /// SourceCollection is the original un-filtered collection of which /// this ICollectionView is a view. /// public override IEnumerable SourceCollection { get { return base.SourceCollection; } } /// /// Set/get a filter callback to filter out items in collection. /// This property will always accept a filter, but the collection view for the /// underlying InnerList or ItemsSource may not actually support filtering. /// Please check /// /// /// Collections assigned to ItemsSource may not support filtering and could throw a NotSupportedException. /// Use property to test if sorting is supported before adding /// to SortDescriptions. /// public override Predicate Filter { get { return ProxiedView.Filter; } set { ProxiedView.Filter = value; } } /// /// Test if this ICollectionView supports filtering before assigning /// a filter callback to . /// public override bool CanFilter { get { return ProxiedView.CanFilter; } } /// /// Set/get Sort criteria to sort items in collection. /// /// ///

/// Clear a sort criteria by assigning SortDescription.Empty to this property. /// One or more sort criteria in form of /// can be used, each specifying a property and direction to sort by. ///

///
/// /// Simpler implementations do not support sorting and will throw a NotSupportedException. /// Use property to test if sorting is supported before adding /// to SortDescriptions. /// public override SortDescriptionCollection SortDescriptions { get { return ProxiedView.SortDescriptions; } } /// /// Test if this ICollectionView supports sorting before adding /// to . /// public override bool CanSort { get { return ProxiedView.CanSort; } } /// /// Returns true if this view really supports grouping. /// When this returns false, the rest of the interface is ignored. /// public override bool CanGroup { get { return ProxiedView.CanGroup; } } /// /// The description of grouping, indexed by level. /// public override ObservableCollection GroupDescriptions { get { return ProxiedView.GroupDescriptions; } } /// /// The top-level groups, constructed according to the descriptions /// given in GroupDescriptions. /// public override ReadOnlyObservableCollection Groups { get { return ProxiedView.Groups; } } /// Re-create the view, using any . public override void Refresh() { IndexedEnumerable indexer = (IndexedEnumerable) Interlocked.Exchange(ref _indexer, null); if (indexer != null) { indexer.Invalidate(); } ProxiedView.Refresh(); } /// /// Enter a Defer Cycle. /// Defer cycles are used to coalesce changes to the ICollectionView. /// public override IDisposable DeferRefresh() { return ProxiedView.DeferRefresh(); } /// Return current item. public override object CurrentItem { get { return ProxiedView.CurrentItem; } } /// /// The ordinal position of the within the (optionally /// sorted and filtered) view. /// public override int CurrentPosition { get { return ProxiedView.CurrentPosition; } } /// Return true if currency is beyond the end (End-Of-File). public override bool IsCurrentAfterLast { get { return ProxiedView.IsCurrentAfterLast; } } /// Return true if currency is before the beginning (Beginning-Of-File). public override bool IsCurrentBeforeFirst { get { return ProxiedView.IsCurrentBeforeFirst; } } /// Move to the first item. public override bool MoveCurrentToFirst() { return ProxiedView.MoveCurrentToFirst(); } /// Move to the previous item. public override bool MoveCurrentToPrevious() { return ProxiedView.MoveCurrentToPrevious(); } /// Move to the next item. public override bool MoveCurrentToNext() { return ProxiedView.MoveCurrentToNext(); } /// Move to the last item. public override bool MoveCurrentToLast() { return ProxiedView.MoveCurrentToLast(); } /// Move to the given item. public override bool MoveCurrentTo(object item) { return ProxiedView.MoveCurrentTo(item); } /// Move CurrentItem to this index public override bool MoveCurrentToPosition(int position) { // // If the index is out of range here, I'll let the // ProxiedView be the one to make that determination. // return ProxiedView.MoveCurrentToPosition(position); } public override event CurrentChangingEventHandler CurrentChanging { add { PrivateCurrentChanging += value; } remove { PrivateCurrentChanging -= value; } } public override event EventHandler CurrentChanged { add { PrivateCurrentChanged += value; } remove { PrivateCurrentChanged -= value; } } #endregion ICollectionView //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties /// /// Return the number of records (or -1, meaning "don't know"). /// A virtualizing view should return the best estimate it can /// without de-virtualizing all the data. A non-virtualizing view /// should return the exact count of its (filtered) data. /// public override int Count { get { return EnumerableWrapper.Count; } } public override bool IsEmpty { get { return ProxiedView.IsEmpty; } } public ICollectionView ProxiedView { get { // VerifyAccess(); return _view; } } #endregion Public Properties //----------------------------------------------------- // // Public Methods // //------------------------------------------------------ #region Public Methods /// Return the index where the given de belongs, or -1 if this index is unknown. /// More precisely, if this returns an index other than -1, it must always be true that /// view[index-1] < de <= view[index], where the comparisons are done via /// the view's IComparer.Compare method (if any). /// /// data item public override int IndexOf(object item) { return EnumerableWrapper.IndexOf(item); } /// /// Return true if the item belongs to this view. The item is assumed to belong to the /// underlying DataCollection; this method merely takes filters into account. /// It is commonly used during collection-changed notifications to determine if the added/removed /// item requires processing. /// Returns true if no filter is set on collection view. /// public override bool PassesFilter(object item) { if (ProxiedView.CanFilter && ProxiedView.Filter != null && item != NewItemPlaceholder && item != ((IEditableCollectionView)this).CurrentAddItem) return ProxiedView.Filter(item); return true; } /// /// Retrieve item at the given zero-based index in this CollectionView. /// /// /// Thrown if index is out of range /// public override object GetItemAt(int index) { // only check lower bound because Count could be expensive if (index < 0) throw new ArgumentOutOfRangeException("index"); return EnumerableWrapper[index]; } #endregion Public Methods #region IEditableCollectionView #region Adding new items /// /// Indicates whether to include a placeholder for a new item, and if so, /// where to put it. /// NewItemPlaceholderPosition IEditableCollectionView.NewItemPlaceholderPosition { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.NewItemPlaceholderPosition; } else { return NewItemPlaceholderPosition.None; } } set { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.NewItemPlaceholderPosition = value; } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "NewItemPlaceholderPosition")); } } } /// /// Return true if the view supports . /// bool IEditableCollectionView.CanAddNew { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CanAddNew; } else { return false; } } } /// /// Add a new item to the underlying collection. Returns the new item. /// After calling AddNew and changing the new item as desired, either /// or should be /// called to complete the transaction. /// object IEditableCollectionView.AddNew() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.AddNew(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "AddNew")); } } /// /// Complete the transaction started by . The new /// item remains in the collection, and the view's sort, filter, and grouping /// specifications (if any) are applied to the new item. /// void IEditableCollectionView.CommitNew() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.CommitNew(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "CommitNew")); } } /// /// Complete the transaction started by . The new /// item is removed from the collection. /// void IEditableCollectionView.CancelNew() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.CancelNew(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "CancelNew")); } } /// /// Returns true if an transaction is in progress. /// bool IEditableCollectionView.IsAddingNew { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.IsAddingNew; } else { return false; } } } /// /// When an transaction is in progress, this property /// returns the new item. Otherwise it returns null. /// object IEditableCollectionView.CurrentAddItem { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CurrentAddItem; } else { return null; } } } #endregion Adding new items #region Removing items /// /// Return true if the view supports and /// . /// bool IEditableCollectionView.CanRemove { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CanRemove; } else { return false; } } } /// /// Remove the item at the given index from the underlying collection. /// The index is interpreted with respect to the view (not with respect to /// the underlying collection). /// void IEditableCollectionView.RemoveAt(int index) { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.RemoveAt(index); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "RemoveAt")); } } /// /// Remove the given item from the underlying collection. /// void IEditableCollectionView.Remove(object item) { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.Remove(item); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "Remove")); } } #endregion Removing items #region Transactional editing of an item /// /// Begins an editing transaction on the given item. The transaction is /// completed by calling either or /// . Any changes made to the item during /// the transaction are considered "pending", provided that the view supports /// the notion of "pending changes" for the given item. /// void IEditableCollectionView.EditItem(object item) { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.EditItem(item); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "EditItem")); } } /// /// Complete the transaction started by . /// The pending changes (if any) to the item are committed. /// void IEditableCollectionView.CommitEdit() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.CommitEdit(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "CommitEdit")); } } /// /// Complete the transaction started by . /// The pending changes (if any) to the item are discarded. /// void IEditableCollectionView.CancelEdit() { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { ecv.CancelEdit(); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "CancelEdit")); } } /// /// Returns true if the view supports the notion of "pending changes" on the /// current edit item. This may vary, depending on the view and the particular /// item. For example, a view might return true if the current edit item /// implements , or if the view has special /// knowledge about the item that it can use to support rollback of pending /// changes. /// bool IEditableCollectionView.CanCancelEdit { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CanCancelEdit; } else { return false; } } } /// /// Returns true if an transaction is in progress. /// bool IEditableCollectionView.IsEditingItem { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.IsEditingItem; } else { return false; } } } /// /// When an transaction is in progress, this property /// returns the affected item. Otherwise it returns null. /// object IEditableCollectionView.CurrentEditItem { get { IEditableCollectionView ecv = ProxiedView as IEditableCollectionView; if (ecv != null) { return ecv.CurrentEditItem; } else { return null; } } } #endregion Transactional editing of an item #endregion IEditableCollectionView #region IEditableCollectionViewAddNewItem /// /// Return true if the view supports . /// bool IEditableCollectionViewAddNewItem.CanAddNewItem { get { IEditableCollectionViewAddNewItem ani = ProxiedView as IEditableCollectionViewAddNewItem; if (ani != null) { return ani.CanAddNewItem; } else { return false; } } } /// /// Add a new item to the underlying collection. Returns the new item. /// After calling AddNewItem and changing the new item as desired, either /// or should be /// called to complete the transaction. /// object IEditableCollectionViewAddNewItem.AddNewItem(object newItem) { IEditableCollectionViewAddNewItem ani = ProxiedView as IEditableCollectionViewAddNewItem; if (ani != null) { return ani.AddNewItem(newItem); } else { throw new InvalidOperationException(SR.Get(SRID.MemberNotAllowedForView, "AddNewItem")); } } #endregion IEditableCollectionViewAddNewItem #region IItemProperties /// /// Returns information about the properties available on items in the /// underlying collection. This information may come from a schema, from /// a type descriptor, from a representative item, or from some other source /// known to the view. /// ReadOnlyCollection IItemProperties.ItemProperties { get { IItemProperties iip = ProxiedView as IItemProperties; if (iip != null) { return iip.ItemProperties; } else { return null; } } } #endregion IItemProperties //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods /// Implementation of IEnumerable.GetEnumerator(). /// This provides a way to enumerate the members of the collection /// without changing the currency. /// protected override IEnumerator GetEnumerator() { return ((IEnumerable) ProxiedView).GetEnumerator(); } #endregion Protected Methods //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods void _OnPropertyChanged(object sender, PropertyChangedEventArgs args) { OnPropertyChanged(args); } void _OnViewChanged(object sender, NotifyCollectionChangedEventArgs args) { // VerifyAccess(); // will throw an exception if caller is not in correct UiContext OnCollectionChanged(args); } void _OnCurrentChanging(object sender, CurrentChangingEventArgs args) { // VerifyAccess(); // will throw an exception if caller is not in correct UiContext if (PrivateCurrentChanging != null) PrivateCurrentChanging(this, args); } void _OnCurrentChanged(object sender, EventArgs args) { // VerifyAccess(); // will throw an exception if caller is not in correct UiContext if (PrivateCurrentChanged != null) PrivateCurrentChanged(this, args); } private IndexedEnumerable EnumerableWrapper { get { if (_indexer == null) { IndexedEnumerable newIndexer = new IndexedEnumerable(ProxiedView, new Predicate(this.PassesFilter)); Interlocked.CompareExchange(ref _indexer, newIndexer, null); } return _indexer; } } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ ICollectionView _view; IndexedEnumerable _indexer; event CurrentChangingEventHandler PrivateCurrentChanging; event EventHandler PrivateCurrentChanged; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK