{"record":{"id":"17ba051429180b85","repo":"HandyOrg/HandyControl","slug":"exceptionstringtable-triggerbase","errorCode":null,"errorMessage":"ExceptionStringTable.CannotHostTriggerMultipleTimesExceptionMessage","messagePattern":"ExceptionStringTable\\.CannotHostTriggerMultipleTimesExceptionMessage","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Shared/System.Windows.Interactivity/TriggerBase.cs","lineNumber":54,"sourceCode":"            return _associatedObject;\n        }\n    }\n\n    protected virtual Type AssociatedObjectTypeConstraint\n    {\n        get\n        {\n            ReadPreamble();\n            return _associatedObjectTypeConstraint;\n        }\n    }\n\n    public void Attach(DependencyObject dependencyObject)\n    {\n        if (!Equals(dependencyObject, AssociatedObject))\n        {\n            if (AssociatedObject != null)\n                throw new InvalidOperationException(ExceptionStringTable\n                    .CannotHostTriggerMultipleTimesExceptionMessage);\n            if (dependencyObject != null &&\n                !AssociatedObjectTypeConstraint.IsInstanceOfType(dependencyObject))\n                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,\n                    ExceptionStringTable.TypeConstraintViolatedExceptionMessage,\n                    new object[]\n                        {GetType().Name, dependencyObject.GetType().Name, AssociatedObjectTypeConstraint.Name}));\n            WritePreamble();\n            _associatedObject = dependencyObject;\n            WritePostscript();\n            Actions.Attach(dependencyObject);\n            OnAttached();\n        }\n    }\n\n    public void Detach()\n    {\n        OnDetaching();","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/HandyOrg/HandyControl/blob/2c0875ebd67326e0c67282967e3e809c69282fee/src/Shared/System.Windows.Interactivity/TriggerBase.cs#L36-L72","documentation":"TriggerBase.Attach throws InvalidOperationException when the trigger already has a non-null AssociatedObject and Attach is called with a different object. A trigger can only ever be hosted on one associated object for its lifetime. This is the Interactivity library enforcing single-host semantics for triggers.","triggerScenarios":"Calling trigger.Attach(newObject) on a trigger already attached elsewhere; adding an already-hosted trigger to another TriggerCollection (via ItemAdded); reusing a trigger instance defined as a shared resource across multiple objects.","commonSituations":"Reusing a Trigger (e.g. EventTrigger) instance across several controls; moving a behavior/trigger from one control to another at runtime; XAML resource sharing pitfalls (x:Shared).","solutions":["Create a new trigger instance per attached object instead of reusing one","Detach the trigger from its current object first (only possible if the API allows) before attaching to another","Declare triggers inline per control rather than as shared resources"],"exampleFix":"// before\nvar trigger = (EventTrigger)FindResource(\"sharedTrigger\");\ntrigger.Attach(grid1);\ntrigger.Attach(grid2); // throws\n// after\ngrid1.Triggers.Add(new EventTrigger { ... });\ngrid2.Triggers.Add(new EventTrigger { ... });","handlingStrategy":"validation","validationCode":"if (trigger.AssociatedObject != null) trigger = CreateNewTrigger();\ntrigger.Attach(target);","typeGuard":null,"tryCatchPattern":"try { trigger.Attach(target); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"host\")) { trigger = CreateNewTrigger(); trigger.Attach(target); }","preventionTips":["Never reuse attached triggers","Check AssociatedObject before Attach","Prefer inline XAML trigger declarations"],"tags":["wpf","interactivity","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"2c0875ebd67326e0c67282967e3e809c69282fee","analyzedAt":"2026-09-14T14:45:29.754Z","contentChangedAt":"2026-09-14T14:45:29.754Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}