HandyOrg/HandyControl · error · InvalidOperationException

ExceptionStringTable.DuplicateItemInCollectionExceptionMessa…

Error message

ExceptionStringTable.DuplicateItemInCollectionExceptionMessage

What it means

AttachableCollection<T>.VerifyAdd guards that each item is added at most once and is non-null. On CollectionChanged it verifies additions; if the item already exists in the internal _snapshot it throws InvalidOperationException with a localized message from ExceptionStringTable naming the duplicate type and collection type.

Solutions

  1. Check Contains before adding: if (!coll.Contains(item)) coll.Add(item)
  2. Create a new behavior instance per target element instead of sharing one instance
  3. Use TryGetValue/deduplication logic when wiring behaviors programmatically

Example fix

// before
var b = new MyBehavior();
Interaction.GetBehaviors(el1).Add(b);
Interaction.GetBehaviors(el2).Add(b); // duplicate — throws
// after
Interaction.GetBehaviors(el1).Add(new MyBehavior());
Interaction.GetBehaviors(el2).Add(new MyBehavior());
Defensive patterns

Strategy: validation

Validate before calling

if (item == null) throw new ArgumentNullException(nameof(item));
if (!behaviors.Contains(item)) behaviors.Add(item);

Type guard

bool CanAdd<T>(ICollection<T> coll, T item) => item != null && !coll.Contains(item);

Try / catch

try { behaviors.Add(behavior); } catch (InvalidOperationException ex) when (ex.Message.Contains("DuplicateItemInCollectionExceptionMessage") || ex.Message.Contains("already")) { /* item already attached — reuse or skip */ }

Prevention

When it happens

Trigger: Adding the same behavior/trigger instance (e.g. a Behavior<T>) to a collection — or to two attachable collections — where it is already present; also triggered indirectly by re-parenting an element that carries an already-attached behavior.

Common situations: Reusing a single Behavior instance across multiple elements or multiple Interaction.GetBehaviors() collections; XAML resource shared via x:Shared="false" duplicates or style setters re-adding the same instance; adding during collection-change reentrancy.

Related errors


AI-assisted analysis of HandyOrg/HandyControl@2c0875ebd6 (2026-09-14). Data as JSON: /api/errors/eebde4331b9802ae. Report an issue: GitHub.

Appendix: source

Thrown at src/Shared/System.Windows.Interactivity/AttachableCollection`1.cs:69

        OnDetaching();
        WritePreamble();
        _associatedObject = null;
        WritePostscript();
    }

    protected abstract void OnAttached();

    protected abstract void OnDetaching();

    internal abstract void ItemAdded(T item);

    internal abstract void ItemRemoved(T item);

    private void VerifyAdd(T item)
    {
        if (item == null) throw new ArgumentNullException(nameof(item));
        if (_snapshot.Contains(item))
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
                ExceptionStringTable.DuplicateItemInCollectionExceptionMessage, new object[]
                {
                    typeof(T).Name,
                    GetType().Name
                }));
    }

    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                var enumerator1 = e.NewItems.GetEnumerator();
                try
                {
                    while (enumerator1.MoveNext())
                    {
                        var current = (T) enumerator1.Current;

View on GitHub (pinned to 2c0875ebd6)