HandyOrg/HandyControl · error · InvalidOperationException
ExceptionStringTable.CannotHostBehaviorMultipleTimesExceptio…
Error message
ExceptionStringTable.CannotHostBehaviorMultipleTimesExceptionMessage
What it means
A Behavior instance in System.Windows.Interactivity can be attached to only one DependencyObject at a time. Attaching it while it is already associated with another object throws InvalidOperationException with CannotHostBehaviorMultipleTimesExceptionMessage. This guards the one-to-one invariant between a behavior and its AssociatedObject.
Solutions
- Create a new behavior instance for each attached object instead of sharing one instance.
- Detach the behavior from its current host (oldHost.Interaction.Behaviors.Remove(behavior)) before attaching it to a new object.
- Check behavior.AssociatedObject == null before calling Attach.
- Clear/rebuild the Behaviors collection on the previous host when moving the behavior.
Example fix
// before
var behavior = new MyBehavior();
element1.SetValue(Interaction.BehaviorsProperty, new BehaviorCollection { behavior });
element2.SetValue(Interaction.BehaviorsProperty, new BehaviorCollection { behavior }); // throws
// after
element1.SetValue(Interaction.BehaviorsProperty, new BehaviorCollection { new MyBehavior() });
element2.SetValue(Interaction.BehaviorsProperty, new BehaviorCollection { new MyBehavior() }); Defensive patterns
Strategy: validation
Validate before calling
if (behavior.AssociatedObject != null && !ReferenceEquals(behavior.AssociatedObject, target))
behavior = (Behavior)Activator.CreateInstance(behavior.GetType()); // fresh instance per host
behavior.Attach(target); Type guard
static bool CanAttach(Behavior b, DependencyObject target) =>
b.AssociatedObject == null && target != null && b.AssociatedType.IsInstanceOfType(target); Try / catch
try { behavior.Attach(target); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CannotHostBehaviorMultipleTimes")) {
// create a new instance of the behavior for this host
} Prevention
- Never share behavior instances between controls; one instance per host.
- Remove behaviors from the old collection before adding to a new one.
- Assert AssociatedObject == null in code that wires behaviors dynamically.
- Be careful with data templates/styles that reuse the same collection instance.
When it happens
Trigger: Calling behavior.Attach(newObject) (directly or via BehaviorCollection.ItemAdded) on a behavior whose AssociatedObject is already non-null and different from newObject.
Common situations: Reusing a single behavior instance across multiple controls; adding the same behavior to a second element's Interaction.Behaviors collection; a collection property-change firing twice so the same behavior is attached twice; re-attaching after forgetting the old host still holds it.
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
- ExceptionStringTable.CannotHostBehaviorCollectionMultipleTim…
- ExceptionStringTable.CannotHostTriggerCollectionMultipleTime…
- ExceptionStringTable.CannotHostTriggerActionMultipleTimesExc…
- ExceptionStringTable.DuplicateItemInCollectionExceptionMessa…
- ExceptionStringTable.TypeConstraintViolatedExceptionMessage
AI-assisted analysis of HandyOrg/HandyControl@2c0875ebd6 (2026-09-14).
Data as JSON: /api/errors/67d2228479199e69.
Report an issue: GitHub.
Appendix: source
Thrown at src/Shared/System.Windows.Interactivity/Behavior.cs:41
return _associatedObject;
}
}
protected Type AssociatedType
{
get
{
ReadPreamble();
return _associatedType;
}
}
public void Attach(DependencyObject dependencyObject)
{
if (!Equals(dependencyObject, AssociatedObject))
{
if (AssociatedObject != null)
throw new InvalidOperationException(ExceptionStringTable
.CannotHostBehaviorMultipleTimesExceptionMessage);
if (dependencyObject != null && !AssociatedType.IsInstanceOfType(dependencyObject))
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
ExceptionStringTable.TypeConstraintViolatedExceptionMessage,
new object[] { GetType().Name, dependencyObject.GetType().Name, AssociatedType.Name }));
WritePreamble();
_associatedObject = dependencyObject;
WritePostscript();
OnAssociatedObjectChanged();
OnAttached();
}
}
public void Detach()
{
OnDetaching();
WritePreamble();
_associatedObject = null;View on GitHub (pinned to 2c0875ebd6)