{"record":{"id":"8090c5f4c8056b70","repo":"stride3d/stride","slug":"a-dependency-object-is-already-attached-to-this-instance-of","errorCode":null,"errorMessage":"A dependency object is already attached to this instance of DependencyPropertyWatcher.","messagePattern":"A dependency object is already attached to this instance of DependencyPropertyWatcher\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/Core/DependencyPropertyWatcher.cs","lineNumber":39,"sourceCode":"        public DependencyPropertyWatcher()\n        {\n        }\n\n        public DependencyPropertyWatcher([NotNull] FrameworkElement attachTo)\n        {\n            Attach(attachTo);\n        }\n\n        public DependencyObject AssociatedObject => frameworkElement;\n\n        public void Attach([NotNull] DependencyObject dependencyObject)\n        {\n            if (dependencyObject == null) throw new ArgumentNullException(nameof(dependencyObject));\n            if (ReferenceEquals(dependencyObject, frameworkElement))\n                return;\n\n            if (frameworkElement != null)\n                throw new InvalidOperationException(\"A dependency object is already attached to this instance of DependencyPropertyWatcher.\");\n            frameworkElement = dependencyObject as FrameworkElement;\n\n            if (frameworkElement == null)\n                throw new ArgumentException(\"The dependency object to attach to the DependencyPropertyWatcher must be a FrameworkElement.\");\n\n            frameworkElement.Loaded += ElementLoaded;\n            frameworkElement.Unloaded += ElementUnloaded;\n            AttachHandlers();\n        }\n\n        public void Detach()\n        {\n            frameworkElement.Loaded -= ElementLoaded;\n            frameworkElement.Unloaded -= ElementUnloaded;\n            DetachHandlers();\n            handlers.Clear();\n            frameworkElement = null;\n        }","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/Core/DependencyPropertyWatcher.cs#L21-L57","documentation":"DependencyPropertyWatcher.Attach can hold exactly one dependency object at a time. Calling Attach on a watcher that already has a frameworkElement attached throws InvalidOperationException, since attaching another object would lose the Loaded/Unloaded subscriptions and change handlers of the previous target.","triggerScenarios":"Calling watcher.Attach(dependencyObject) twice on the same watcher instance with different (or any) dependency objects while frameworkElement is already non-null and the new object is not the same reference.","commonSituations":"Reusing a single watcher across pages/controls without detaching; subscribing the watcher in a constructor that runs again after re-templating; holding watchers in static fields shared by multiple views.","solutions":["Create a new DependencyPropertyWatcher instance for each dependency object.","Detach or dispose the existing watcher (remove handlers / null out frameworkElement) before attaching a new object.","Keep one watcher per view instead of storing watchers in shared/static state."],"exampleFix":"// before\nwatcher.Attach(oldElement);\nwatcher.Attach(newElement); // throws\n// after\nwatcher = new DependencyPropertyWatcher(path, onChanged);\nwatcher.Attach(newElement);","handlingStrategy":"validation","validationCode":"if (watcher != null && watcher.IsAttached)\n    watcher = new DependencyPropertyWatcher(path, onChanged);\nwatcher.Attach(dependencyObject);","typeGuard":"bool CanAttach(DependencyPropertyWatcher w) => w == null || !w.IsAttached;","tryCatchPattern":"try { watcher.Attach(dependencyObject); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"already attached\")) { watcher = new DependencyPropertyWatcher(path, onChanged); watcher.Attach(dependencyObject); }","preventionTips":["Keep one watcher instance per target object; create rather than reuse.","Release watchers on view unload (Unloaded/Dispose) instead of re-attaching.","Avoid storing watchers in static or shared fields used by multiple views."],"tags":["wpf","dependency-properties","lifecycle"],"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"}