dotnet/wpf · error · InvalidOperationException
SR.ObjectDataProviderParameterCollectionIsNotInUse
Error message
SR.ObjectDataProviderParameterCollectionIsNotInUse
What it means
ParameterCollection (backing ObjectDataProvider's ConstructorParameters/ObjectInstance/MethodParameters) is read-only once it is in active use by an ObjectDataProvider; CheckReadOnly throws InvalidOperationException with SR.ObjectDataProviderParameterCollectionIsNotInUse on any mutation. WPF marks the collection in use when the provider starts constructing/invoking, so late mutation would corrupt provider state.
Solutions
- Wait until the provider is idle: only mutate MethodParameters/ConstructorParameters outside active refresh cycles (e.g. before the first Refresh, or after the binding completes).
- Detach first: clear the binding (set the Binding's source differently) or reassign a fresh ObjectDataProvider with new parameters.
- Batch parameter changes and apply them on the dispatcher at a safe point (Dispatcher.BeginInvoke at Background priority), then call provider.Refresh().
- Wrap mutations in try-catch InvalidOperationException to detect the in-use state and defer the change.
Example fix
// before
provider.MethodParameters.Clear(); // InvalidOperationException: collection is not in use
// after
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
provider.MethodParameters.Clear();
provider.MethodParameters.Add(newValue);
provider.Refresh();
})); Defensive patterns
Strategy: try-catch
Validate before calling
// mutate parameters only before first use; after Refresh, defer mutations bool safe = !isProviderActive; // track provider activity around Refresh/construction
Try / catch
try { provider.MethodParameters.Add(value); provider.Refresh(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("use"))
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{ provider.MethodParameters.Add(value); provider.Refresh(); }));
} Prevention
- Never mutate MethodParameters/ConstructorParameters from inside the created object's constructor.
- Change parameters only while the ObjectDataProvider is idle; call Refresh afterwards.
- Replace an in-use provider with a new instance instead of mutating its collection.
- Defer parameter changes to the dispatcher queue at background priority.
When it happens
Trigger: Adding/inserting/removing/clearing/setting items in a ParameterCollection that ObjectDataProvider has already flagged in-use — e.g. mutating MethodParameters during the object's construction callback, from a data-binding converter, or after Refresh without detaching.
Common situations: XAML data binding where code-behind or a converter modifies ObjectDataProvider.MethodParameters while the provider is mid-creation; mutating parameters inside the target object's constructor triggered by the provider.
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
- Cannot countersign an unsigned package.
- Cannot read Page properties because it is not in a tree…
- Cannot sign read-only file.
- Exception of type 'System.InvalidOperationException' was…
- NotSupportedException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/201502d7166b59b4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/ParameterCollection.cs:170
{
base.ClearItems();
}
#endregion Internal Methods
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
private void CheckReadOnly()
{
if (this.IsReadOnly)
{
throw new InvalidOperationException(SR.ObjectDataProviderParameterCollectionIsNotInUse);
}
}
/// <summary>
/// notify ObjectDataProvider that the parameters have changed
/// </summary>
private void OnCollectionChanged()
{
_parametersChanged(this);
}
#endregion Private Methods
//------------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------View on GitHub (pinned to 81131a70a4)