dotnet/wpf · error · InvalidOperationException
SR.RemovingPlaceholder
Error message
SR.RemovingPlaceholder
What it means
RemoveImpl throws InvalidOperationException with the RemovingPlaceholder message when the caller attempts to remove the CollectionView.NewItemPlaceholder item. The placeholder is a virtual marker row (shown when NewItemPlaceholderPosition is set), not a real item in the collection, so it can never be removed.
Solutions
- Check for CollectionView.NewItemPlaceholder and skip it before calling Remove/RemoveAt.
- Enumerate the underlying collection instead of the view when doing bulk removals, so the placeholder never appears.
- In DataGrid delete handlers, guard: if (view.IndexOf(item) is the placeholder or item == CollectionView.NewItemPlaceholder) return.
- Disable delete UI for the placeholder row via a row style/validation.
Example fix
// before
view.Remove(selectedItem);
// after
if (!Equals(selectedItem, CollectionView.NewItemPlaceholder))
view.Remove(selectedItem); Defensive patterns
Strategy: type-guard
Validate before calling
// C# if (Equals(item, CollectionView.NewItemPlaceholder)) return; // skip
Type guard
bool IsPlaceholder(object item) => Equals(item, CollectionView.NewItemPlaceholder);
Try / catch
try { view.Remove(item); }
catch (InvalidOperationException ex) when (ex.Message.Contains("placeholder")) { /* skip placeholder */ } Prevention
- Filter out CollectionView.NewItemPlaceholder in delete handlers.
- Enumerate the source collection for bulk deletes, not the view.
- Disable delete on the placeholder row in the UI.
When it happens
Trigger: Calling Remove(CollectionView.NewItemPlaceholder) or RemoveAt(indexOfPlaceholder) — commonly when code enumerates the view and tries to delete 'all visible rows' including the placeholder row, or a user deletes the placeholder row in a grid.
Common situations: DataGrid bound to a view with NewItemPlaceholderPosition.AtBeginning/AtEnd and a delete handler acting on the selected item without checking for the placeholder; clearing loops that iterate the view's items directly.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.CannotEditPlaceholder
- SR.Format(SR.MemberNotAllowedDuringTransaction…
- ArgumentNullException(nameof(value))
- (no message) NotSupportedException
- NotImplementedException (ConvertBack not supported)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/9e464fdbb6556d69.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingListCollectionView.cs:897
/// Remove the given item from the underlying collection.
/// </summary>
public void Remove(object item)
{
if (IsEditingItem || IsAddingNew)
throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Remove"));
VerifyRefreshNotDeferred();
int index = InternalIndexOf(item);
if (index >= 0)
{
RemoveImpl(item, index);
}
}
private void RemoveImpl(object item, int index)
{
if (item == CollectionView.NewItemPlaceholder)
throw new InvalidOperationException(SR.RemovingPlaceholder);
BindingOperations.AccessCollection(InternalList,
() =>
{
ProcessPendingChanges();
// the pending changes may have moved (or even removed) the
// item. Verify the index.
if (index >= InternalList.Count || !System.Windows.Controls.ItemsControl.EqualsEx(item, GetItemAt(index)))
{
index = InternalList.IndexOf(item);
if (index < 0)
return;
}
// convert the index from "view-relative" to "list-relative"
if (_isGrouping)
{View on GitHub (pinned to 81131a70a4)