dotnet/wpf · error · InvalidOperationException

SR.NoCheckOrChangeWhenDeferred

Error message

SR.NoCheckOrChangeWhenDeferred

What it means

CollectionView throws InvalidOperationException (SR.NoCheckOrChangeWhenDeferred) when callers attempt to check or change currency (e.g. via VerifyRefreshNotDeferred) while a Refresh is deferred through DeferRefresh. During a defer scope the view's state is intentionally stale, so currency operations and changes are rejected to avoid acting on incorrect data.

Solutions

  1. Move current item before entering the DeferRefresh scope or after disposing the DeferHelper
  2. Restructure code so currency operations happen outside the defer block
  3. Check collectionView.IsRefreshDeferred and skip/postpone currency changes until the defer ends

Example fix

// before
using (view.DeferRefresh()) {
    view.Filter = p;
    view.MoveCurrentToFirst(); // InvalidOperationException
}
// after
view.Filter = p;
view.MoveCurrentToFirst();
// or do currency changes after the using block
Defensive patterns

Strategy: validation

Validate before calling

if (view.IsRefreshDeferred)
    throw new InvalidOperationException("Refresh is deferred; postpone currency changes.");
view.MoveCurrentToFirst();

Type guard

bool currencySafe = view is CollectionView cv && !cv.IsRefreshDeferred;

Try / catch

try { view.MoveCurrentTo(item); }
catch (InvalidOperationException) { /* defer ended elsewhere */ view.MoveCurrentTo(item); }

Prevention

When it happens

Trigger: Calling MoveCurrentTo*, MoveCurrentToPosition, or other currency/state-changing members while inside a using (collectionView.DeferRefresh()) block (IsRefreshDeferred == true).

Common situations: Batch-updating Filter/SortDescriptions inside a DeferRefresh scope and also trying to move current item; helper code that sets selection/currency while deferring refresh; nested helpers that open a defer scope around selection changes.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/d621c5107182690e. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/CollectionView.cs:1422

        internal virtual bool HasReliableHashCodes()
        {
            // default implementation - sample the first item
            return (IsEmpty || HashHelper.HasReliableHashCode(GetItemAt(0)));
        }

        // helper to validate that we are not in the middle of a DeferRefresh
        // and throw if that is the case.
        internal void VerifyRefreshNotDeferred()
        {
            if (AllowsCrossThreadChanges)
                VerifyAccess();

            // If the Refresh is being deferred to change filtering or sorting of the
            // data by this CollectionView, then CollectionView will not reflect the correct
            // state of the underlying data.

            if (IsRefreshDeferred)
                throw new InvalidOperationException(SR.NoCheckOrChangeWhenDeferred);
        }

        internal void InvalidateEnumerableWrapper()
        {
            IndexedEnumerable wrapper = (IndexedEnumerable) Interlocked.Exchange(ref _enumerableWrapper, null);
            wrapper?.Invalidate();
        }

        internal ReadOnlyCollection<ItemPropertyInfo> GetItemProperties()
        {
            IEnumerable collection = SourceCollection;
            if (collection == null)
                return null;

            IEnumerable properties = null;

            ITypedList itl = collection as ITypedList;
            Type itemType;

View on GitHub (pinned to 81131a70a4)