{"record":{"id":"cbbdde6e34ddc114","repo":"stride3d/stride","slug":"this-behaviorcollection-has-already-been-attached-to-a","errorCode":null,"errorMessage":"This BehaviorCollection has already been attached to a dependency object.","messagePattern":"This BehaviorCollection has already been attached to a dependency object\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/Interactivity/BehaviorCollection.cs","lineNumber":44,"sourceCode":"        public BehaviorCollection Clone()\n        {\n            var clone = new BehaviorCollection();\n            foreach (var behavior in Items)\n            {\n                clone.Add((Behavior)behavior.Clone());\n            }\n            return clone;\n        }\n\n        public void Attach([NotNull] DependencyObject dependencyObject)\n        {\n            if (dependencyObject == null) throw new ArgumentNullException(nameof(dependencyObject));\n            // Aleady attached\n            if (ReferenceEquals(AssociatedObject, dependencyObject))\n                return;\n\n            if (AssociatedObject != null)\n                throw new InvalidOperationException(\"This BehaviorCollection has already been attached to a dependency object.\");\n\n            AssociatedObject = dependencyObject;\n            var behaviors = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(dependencyObject);\n            foreach (var behavior in this)\n            {\n                behaviors.Add(behavior);\n            }\n        }\n\n        public void Detach()\n        {\n            if (AssociatedObject != null)\n            {\n                var behaviors = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(AssociatedObject);\n                foreach (var behavior in this)\n                {\n                    behaviors.Remove(behavior);\n                }","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/Interactivity/BehaviorCollection.cs#L26-L62","documentation":"BehaviorCollection.Attach throws InvalidOperationException when the collection's AssociatedObject is already set to a different dependency object. Each BehaviorCollection instance may be attached to exactly one object for its lifetime; re-attaching is an unsupported state transition.","triggerScenarios":"Calling Attach on a BehaviorCollection whose AssociatedObject is non-null and different from the new dependencyObject; reusing a BehaviorCollection across windows/controls; re-attaching a collection stored in a shared resource.","commonSituations":"Sharing a BehaviorCollection defined in App.xaml resources between multiple controls; recycling controls in virtualized lists while keeping behavior collections; calling Attach twice after re-templating.","solutions":["Create a new BehaviorCollection for each dependency object instead of reusing one.","Detach from the old object (set AssociatedObject to null / use Detach if available) before re-attaching.","Store behaviors as per-instance resources rather than shared StaticResource; use DynamicResource or x:Shared=\"False\".","Guard with ReferenceEquals(AssociatedObject, target) checks — Attach is a no-op for the same object."],"exampleFix":"// before\nvar shared = (BehaviorCollection)Application.Current.Resources[\"MyBehaviors\"];\nshared.Attach(controlA);\nshared.Attach(controlB); // throws\n// after\nvar forA = new BehaviorCollection();\nforA.AddRange(shared);\nforA.Attach(controlA);","handlingStrategy":"try-catch","validationCode":"if (behaviors.AssociatedObject != null && !ReferenceEquals(behaviors.AssociatedObject, target))\n    behaviors = CloneBehaviors(behaviors); // make a per-control copy\nbehaviors.Attach(target);","typeGuard":"static bool CanAttach(BehaviorCollection c, DependencyObject target) => c.AssociatedObject == null || ReferenceEquals(c.AssociatedObject, target);","tryCatchPattern":"try { behaviors.Attach(control); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"already been attached\"))\n{\n    var copy = new BehaviorCollection();\n    copy.AddRange(behaviors);\n    copy.Attach(control);\n}","preventionTips":["Never share BehaviorCollection instances via StaticResource; use x:Shared=\"False\" or per-instance creation","Detach before re-attaching to another object","Assume Attach is one-shot per collection instance"],"tags":["wpf","invalidoperation","behaviors","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}