using System.Windows; using System.Windows.Controls; namespace AxCopilot.Views; /// /// TranscriptVisualItem의 지연 생성 호스트. /// VirtualizingStackPanel Recycling 모드에서 효율적으로 동작합니다: /// - Loaded: 콘텐츠 구체화 (GetOrCreateElement) /// - Unloaded: 콘텐츠 참조 해제 (재활용 시 메모리 절약) /// - DataContextChanged: 재활용된 컨테이너에 새 아이템 바인딩 /// public sealed class TranscriptVisualHost : ContentControl { public TranscriptVisualHost() { HorizontalAlignment = HorizontalAlignment.Stretch; HorizontalContentAlignment = HorizontalAlignment.Stretch; DataContextChanged += OnDataContextChanged; Loaded += OnLoaded; Unloaded += OnUnloaded; } private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { // 재활용 시: 이전 콘텐츠 즉시 해제 후 새 아이템 구체화 if (e.OldValue != null && e.NewValue != e.OldValue) Content = null; if (IsLoaded) SyncContent(); } private void OnLoaded(object sender, RoutedEventArgs e) => SyncContent(); private void OnUnloaded(object sender, RoutedEventArgs e) { // 화면 밖으로 스크롤된 항목의 콘텐츠 참조 해제 // 단, DataContext가 이미 새 아이템으로 바뀐 경우(재활용 중)는 건드리지 않음 // → Unloaded가 DataContextChanged 이후 호출되는 레이스 컨디션 방지 if (DataContext is not TranscriptVisualItem) Content = null; } private void SyncContent() { if (DataContext is TranscriptVisualItem item) { Content = item.GetOrCreateElement(); return; } if (DataContext is UIElement element) { Content = element; return; } Content = null; } }