HandyOrg/HandyControl · error · InvalidOperationException

ExceptionStringTable.CannotHostTriggerActionMultipleTimesExc…

Error message

ExceptionStringTable.CannotHostTriggerActionMultipleTimesExceptionMessage

What it means

TriggerActionCollection.ItemAdded throws InvalidOperationException when a TriggerAction that already has a host (IsHosted == true) is added to another collection. The Interactivity library forbids one TriggerAction instance from being attached to multiple hosts, since Attach hooks it to a single AssociatedObject. This guards the invariant that each action belongs to exactly one trigger/host.

Solutions

  1. Create a new TriggerAction instance for each trigger instead of sharing one resource instance
  2. Remove the action from its current collection (or set IsHosted=false via a new instance) before adding elsewhere
  3. In XAML, avoid using a single action defined in resources across multiple triggers; declare it inline per trigger

Example fix

// before
<Trigger Action="{StaticResource SharedAction}"/>
<Trigger Action="{StaticResource SharedAction}"/>
// after
<Trigger><local:MyAction/></Trigger>
<Trigger><local:MyAction/></Trigger>
Defensive patterns

Strategy: validation

Validate before calling

if (actions.Contains(action)) return; // or create a new instance
collection.Add(action);

Try / catch

try { collection.Add(action); } catch (InvalidOperationException ex) when (ex.Message.Contains("host")) { collection.Add((TriggerAction)Activator.CreateInstance(action.GetType())); }

Prevention

When it happens

Trigger: Adding the same TriggerAction instance (from XAML resources or code) into a second TriggerActionCollection, e.g. reusing a shared <TriggerAction> resource in multiple triggers or calling collection.Add(action) twice.

Common situations: Defining an action as a shared resource (x:Shared not considered) and referencing it from multiple triggers; programmatically moving an action between behaviors/triggers without removing it first; accidentally adding the same instance twice in code.

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 HandyOrg/HandyControl@2c0875ebd6 (2026-09-14). Data as JSON: /api/errors/b68a38567ebdfe6d. Report an issue: GitHub.

Appendix: source

Thrown at src/Shared/System.Windows.Interactivity/TriggerActionCollection.cs:20

using System.Windows;

namespace HandyControl.Interactivity;

public class TriggerActionCollection : AttachableCollection<TriggerAction>
{
    internal TriggerActionCollection()
    {
    }

    protected override Freezable CreateInstanceCore()
    {
        return new TriggerActionCollection();
    }

    internal override void ItemAdded(TriggerAction item)
    {
        if (item.IsHosted)
            throw new InvalidOperationException(ExceptionStringTable
                .CannotHostTriggerActionMultipleTimesExceptionMessage);
        if (AssociatedObject != null)
            item.Attach(AssociatedObject);
        item.IsHosted = true;
    }

    internal override void ItemRemoved(TriggerAction item)
    {
        if (((IAttachedObject) item).AssociatedObject != null)
            item.Detach();
        item.IsHosted = false;
    }

    protected override void OnAttached()
    {
        foreach (var action in this)
            action.Attach(AssociatedObject);
    }

View on GitHub (pinned to 2c0875ebd6)