Remove code-behind theme classes, consolidate theme definitions into ResourceDictionary format,
add TransitionProvider and SharedTokenResourceValue infrastructure, and remove redundant styles.
- OnAttachedToVisualTree: re-subscribe Target.ScrollChanged with
idempotent -= before += to handle re-attach correctly
- OnDetachedFromVisualTree: unsubscribe ScrollChanged, Cancel+Dispose
_cancellationTokenSource (does not clear Target to support re-attach)
- OnClick: Dispose old CTS before creating new one
- MotionGhostControl: unsubscribe SizeChanged and reset _layout/
_maskCenterFrame to null, enabling correct re-initialization on
re-attach when Content changes while detached
- GradientColorPickerTrack: clear thumbs from LogicalChildren/
VisualChildren on detach, preventing stale thumbs on re-attach
when GradientValue becomes null while detached
- CollapseItem: reset InAnimating flag on detach, preventing the
control from being stuck in animating state after re-attach
- RangeInfoPickerInput: clear _topLevel reference on detach to
prevent holding a stale TopLevel (window) reference
- TreeViewItem: clear OwnerTreeView on detach to prevent stale
tree operations during detached period and avoid GC retention
- Card: simplify delegate instantiation style (cosmetic only)
Partially addresses issue 2.1 in docs/Issues/AtomUI_issues.md.
Remaining: AbstractBackTopFloatButtonHost, PopupConfirm,
NotificationCard, NavMenuItem, Collapse, Card token scope.
The code was already using named methods (OnFloatButtonGroupOpenRequest/
OnFloatButtonGroupCloseRequest) with CompositeDisposable cleanup.
Update tracking doc to reflect actual state.
- Add OnClick/OnClose internal properties to NotificationCard to carry
per-notification callbacks without capturing local variables
- Replace PointerPressed lambda with static OnNotificationPointerPressed
(zero closure allocation, reads callback from card.OnClick)
- Replace NotificationClosed lambda with instance OnNotificationClosed
(accesses _items via 'this', no local variable capture)
- Update AtomUI_issues.md: mark 1.2 as fixed, remove from P8 list
Modal methods (ShowMessageBoxModalAsync, ShowMessageModalAsync,
ShowDialogModalAsync x2): OpenAsync() awaits dialog close, so cleanup
is moved after await tsc.Task — no Closed subscription needed.
Non-modal methods (ShowMessageBoxAsync, ShowMessageAsync,
ShowDialogAsync x2): OpenAsync() returns after dialog is shown, so
Closed lambda is retained as the only close notification point.
The lambda is harmless: Closed fires exactly once, dialog is removed
from parent and GC'd immediately after, releasing the closure.
- Update AtomUI_issues.md: mark 1.1 as fixed, remove from P3 list
- Delete performance_memory_leak.md (tracking moved to AtomUI_issues.md)
- INotifyTransitionCompleted interface now extends IDisposable
- AbstractNotifiableTransition<T>.Dispose() disposes Subject<bool> and nulls it
- NotifyTransitionCompleted() guards against null _subject (post-dispose)
- CompletedObservable throws ObjectDisposedException if accessed after Dispose
- AbstractMotion.RunTransitions: dispose all Transitions after await completes
(covers both normal completion and Task.Delay timeout path)
- AbstractMotion.ConfigureTransitions: dispose existing Transitions before Clear
to prevent Subject leaks when transitions are rebuilt
- Update performance_memory_leak.md: 32/39 fixed (82.1%), High 8/8 all done
Items is an internal ItemCollection owned by Form with identical lifetime.
The subscription cannot leak across lifetimes: when Form is GC'd, Items and
its event subscriptions are collected with it. Mark 3.4 as false positive in docs.
- Replace anonymous lambda with named method to allow precise -= unsubscription
- Prevents subscription leak when Items is replaced by an external CollectionView
- Update performance_memory_leak.md: 32/39 fixed (82.1%), Medium 16/19
- Mirror the same WeakCollectionChangedForwarder pattern applied to ListCollectionView (29452afe)
- Add IDisposable to DataGridCollectionView class declaration
- Add _collectionChangedForwarder field (WeakCollectionChangedForwarder?)
- Replace anonymous lambda subscription with forwarder in constructor
- Add Dispose() for eager cleanup
- Add WeakCollectionChangedForwarder nested class with self-unsubscribe on GC
- All Critical (P0) issues now fully resolved
- Update performance_memory_leak.md: 31/39 fixed (79.5%), Critical 7/7
- Add WeakCollectionChangedForwarder nested class: source holds strong ref to
forwarder, forwarder holds WeakReference<ListCollectionView> — prevents the
source collection from rooting the view
- Self-unsubscribes on next event after view is GC'd; no lingering delegate
- Keep IDisposable.Dispose() for eager cleanup when ItemsSource changes in ListView
- ListView: track _ownsCollectionView flag and call Dispose() on old view only
when we created it (not user-provided IListCollectionView)
- Remove OnDetachedFromVisualTree disposal to avoid breaking reattach scenarios
(tab switching, panel rebuilds, etc.) — WeakReference handles lifetime safely
- Update performance_memory_leak.md: mark 1.1 as fixed, progress 30/39 (76.9%)