示例#1
0
        /// <summary>
        /// Suspends the change notifications until the returned <see cref="IDisposable"/> is disposed.
        /// <example>
        /// <code>
        /// <![CDATA[
        /// var fastCollection = new FastObservableCollection<int>();
        /// using (fastCollection.SuspendChangeNotificaftions())
        /// {
        ///     // Adding or removing events inside here will not raise events
        ///     fastCollection.Add(1);
        ///     fastCollection.Add(2);
        ///     fastCollection.Add(3);
        ///
        ///     fastCollection.Remove(3);
        ///     fastCollection.Remove(2);
        ///     fastCollection.Remove(1);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        /// </summary>
        /// <param name="mode">The suspension Mode.</param>
        /// <returns>IDisposable.</returns>
        public IDisposable SuspendChangeNotifications(SuspensionMode mode)
        {
            if (_suspensionContext == null)
            {
                // Create new context
                _suspensionContext = new SuspensionContext <T>(mode);
            }
            else if (_suspensionContext != null && _suspensionContext.Mode != mode)
            {
                throw Log.ErrorAndCreateException <InvalidOperationException>("Cannot change mode during another active suspension.");
            }

            return(new DisposableToken <FastObservableCollection <T> >(
                       this,
                       x =>
            {
                x.Instance._suspensionContext.Count++;
            },
                       x =>
            {
                x.Instance._suspensionContext.Count--;
                if (x.Instance._suspensionContext.Count == 0)
                {
                    if (x.Instance.IsDirty)
                    {
                        x.Instance.IsDirty = false;
                        x.Instance.NotifyChanges();
                    }

                    x.Instance._suspensionContext = null;
                }
            }, _suspensionContext));
        }
示例#2
0
        /// <summary>
        /// Removes the specified items from the collection without causing a change notification for all items.
        /// <para />
        /// This method will raise a change notification at the end.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="mode">The suspension mode.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="collection"/> is <c>null</c>.</exception>
        public void RemoveItems(IEnumerable <T> collection, SuspensionMode mode)
        {
            Argument.IsNotNull("collection", collection);

            using (SuspendChangeNotifications(mode))
            {
                foreach (var item in collection)
                {
                    Remove(item);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Transforms the <see cref="SuspensionMode"/> into its equivalent <see cref="NotifyCollectionChangedAction"/>.
        /// </summary>
        /// <param name="mode">The suspension mode.</param>
        /// <returns>The equivalent <see cref="NotifyCollectionChangedAction"/>.</returns>
        private static NotifyCollectionChangedAction ModeToAction(SuspensionMode mode)
        {
            // Only transform modes Adding and Removing, others fail
            switch (mode)
            {
            case SuspensionMode.Adding: return(NotifyCollectionChangedAction.Add);

            case SuspensionMode.Removing: return(NotifyCollectionChangedAction.Remove);

            default: throw new ArgumentException($"Wrong mode '{mode}' for constructor.");
            }
        }
示例#4
0
        /// <summary>
        /// Inserts the elements of the specified collection at the specified index.
        /// <para />
        /// This method will raise a change notification at the end.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="index">The start index.</param>
        /// <param name="mode">The suspension mode.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="collection"/> is <c>null</c>.</exception>
        public virtual void InsertItems(IEnumerable <T> collection, int index, SuspensionMode mode)
        {
            Argument.IsNotNull("collection", collection);

            using (SuspendChangeNotifications(mode))
            {
                foreach (var item in collection)
                {
                    Insert(index++, item);
                }
            }
        }
示例#5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NotifyRangedCollectionChangedEventArgs"/> class.
        /// </summary>
        /// <param name="changedItems">The changed items.</param>
        /// <param name="indices">The indices.</param>
        /// <param name="mode">The suspension mode.</param>
        /// <param name="action">The action.</param>
        /// <remarks>This is only for use of <see cref="Catel.Collections.SuspensionMode.MixedBash"/>.</remarks>
        public NotifyRangedCollectionChangedEventArgs(IList changedItems, IList <int> indices, SuspensionMode mode, NotifyCollectionChangedAction action)
            : base(EnsureModeAndAction(mode, action), changedItems, (indices != null && indices.Count != 0) ? indices[0] : -1)
        {
            Argument.IsNotNull(nameof(changedItems), changedItems);
            Argument.IsNotNull(nameof(indices), indices);
            // ReSharper disable once PossibleNullReferenceException
            Argument.IsNotOutOfRange(nameof(indices), indices.Count, changedItems.Count, changedItems.Count);

            ChangedItems   = changedItems;
            Indices        = indices;
            SuspensionMode = mode;
        }
示例#6
0
        /// <summary>
        /// Adds the specified items to the collection without causing a change notification for all items.
        /// <para />
        /// This method will raise a change notification at the end.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="mode">The suspension mode.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="collection"/> is <c>null</c>.</exception>
        public void AddItems(IEnumerable collection, SuspensionMode mode)
        {
            Argument.IsNotNull("collection", collection);

            using (SuspendChangeNotifications(mode))
            {
                foreach (var item in collection)
                {
                    ((IList)this).Add(item);
                }
            }
        }
示例#7
0
        /// <summary>
        /// The ensure mode and action.
        /// </summary>
        /// <param name="mode">The suspension mode.</param>
        /// <param name="action">The action.</param>
        /// <returns>The <see cref="NotifyCollectionChangedAction"/>.</returns>
        private static NotifyCollectionChangedAction EnsureModeAndAction(SuspensionMode mode, NotifyCollectionChangedAction action)
        {
            // Check for mixed modes except for Mixed, others fail
            if (mode == SuspensionMode.Mixed || !mode.IsMixedMode())
            {
                throw new ArgumentException($"Wrong mode '{mode}' for constructor.");
            }

            // Check for action Add or Remove, others fail
            switch (action)
            {
            case NotifyCollectionChangedAction.Add:
            case NotifyCollectionChangedAction.Remove: return(action);

            default: throw new ArgumentException($"Wrong action '{action}' for constructor.");
            }
        }
示例#8
0
        /// <summary>
        /// Suspends the change notifications until the returned <see cref="IDisposable"/> is disposed.
        /// <example>
        /// <code>
        /// <![CDATA[
        /// var fastCollection = new FastBindingList<int>();
        /// using (fastCollection.SuspendChangeNotificaftions())
        /// {
        ///     // Adding or removing events inside here will not raise events
        ///     fastCollection.Add(1);
        ///     fastCollection.Add(2);
        ///     fastCollection.Add(3);
        ///
        ///     fastCollection.Remove(3);
        ///     fastCollection.Remove(2);
        ///     fastCollection.Remove(1);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        /// </summary>
        /// <param name="mode">The suspension Mode.</param>
        /// <returns>IDisposable.</returns>
        public IDisposable SuspendChangeNotifications(SuspensionMode mode)
        {
            if (_suspensionContext is null)
            {
                // Create new context
                _suspensionContext = new ExtendedSuspensionContext <T>(mode);
            }
            else if (_suspensionContext.Mode != mode)
            {
                throw Log.ErrorAndCreateException <InvalidOperationException>("Cannot change mode during another active suspension.");
            }

            return(new DisposableToken <FastBindingList <T> >(
                       this,
                       x =>
            {
                if (x.Instance._suspensionContext.Count == 0)
                {
                    x.Instance.RaiseListChangedEvents = false;
                    x.Instance.IsDirty = true;
                }
                x.Instance._suspensionContext.Count++;
            },
                       x =>
            {
                x.Instance._suspensionContext.Count--;
                if (x.Instance._suspensionContext.Count == 0)
                {
                    x.Instance.RaiseListChangedEvents = true;
                    x.Instance.IsDirty = false;
                    x.Instance.NotifyChanges();

                    x.Instance._suspensionContext = null;
                }
            }, _suspensionContext));
        }
示例#9
0
 /// <summary>
 /// The is mixed mode.
 /// </summary>
 /// <param name="suspensionMode">The suspension Mode.</param>
 /// <returns><c>True</c> if <see cref="SuspensionMode"/> is one of the mixed modes; otherwise, <c>false</c>.</returns>
 public static bool IsMixedMode(this SuspensionMode suspensionMode)
 {
     return(MixedModes.Contains(suspensionMode));
 }
示例#10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ExtendedSuspensionContext{T}" /> class.
 /// </summary>
 /// <param name="mode">The suspension mode.</param>
 public ExtendedSuspensionContext(SuspensionMode mode)
 {
     _suspensionMode = mode;
 }
示例#11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SuspensionContext{T}" /> class.
 /// </summary>
 /// <param name="mode">The suspension mode.</param>
 public SuspensionContext(SuspensionMode mode)
 {
     _suspensionMode = mode;
 }
        /// <summary>
        /// Creates the bash event args list.
        /// </summary>
        /// <param name="suspensionContext">The suspension context.</param>
        /// <param name="suspensionMode">The suspension mode.</param>
        /// <typeparam name="T">The type of collection item.</typeparam>
        /// <returns>The <see cref="IList{NotifyRangedCollectionChangedEventArgs}"/>.</returns>
        private static IList <NotifyRangedCollectionChangedEventArgs> CreateBashEvents <T>(this SuspensionContext <T> suspensionContext, SuspensionMode suspensionMode)
        {
            var i                  = 0;
            var changedItems       = new List <T>();
            var changedItemIndices = new List <int>();
            var previousAction     = (NotifyCollectionChangedAction?)null;
            var eventArgsList      = new List <NotifyRangedCollectionChangedEventArgs>();

            foreach (var action in suspensionContext.MixedActions)
            {
                // If action changed, create event args for remembered items
                if (previousAction.HasValue && action != previousAction.Value)
                {
                    // Create and add event args
                    eventArgsList.Add(new NotifyRangedCollectionChangedEventArgs(changedItems, changedItemIndices, suspensionMode, previousAction.Value));

                    // Reset lists
                    changedItems       = new List <T>();
                    changedItemIndices = new List <int>();
                }

                // Remember item and index
                changedItems.Add(suspensionContext.ChangedItems[i]);
                changedItemIndices.Add(suspensionContext.ChangedItemIndices[i]);

                // Update to current action
                previousAction = action;

                i++;
            }

            // Create event args for last item(s)
            if (changedItems.Count != 0 && previousAction != null)
            {
                eventArgsList.Add(new NotifyRangedCollectionChangedEventArgs(changedItems, changedItemIndices, suspensionMode, previousAction.Value));
            }

            return(eventArgsList);
        }
示例#13
0
 public new IDisposable SuspendChangeNotifications(SuspensionMode mode)
 {
     _initialCount = Count;
     return(base.SuspendChangeNotifications(mode));
 }