@@ -1593,33 +1593,51 @@ private void CachedValueChanged()
15931593 } ) ) ;
15941594 }
15951595
1596- private Point PointToLocal ( double x , double y , UIElement target )
1596+ private static bool TryPointToLocal ( double x , double y , UIElement target , out Point result )
15971597 {
1598- Point positionFromScreen = target . PointToScreen ( new Point ( x , y ) ) ;
1599- PresentationSource source = PresentationSource . FromVisual ( target ) ;
1600- Point targetPoints = source . CompositionTarget . TransformFromDevice . Transform ( positionFromScreen ) ;
1601- return targetPoints ;
1598+ result = default ;
1599+ try
1600+ {
1601+ Point positionFromScreen = target . PointToScreen ( new Point ( x , y ) ) ;
1602+ PresentationSource source = PresentationSource . FromVisual ( target ) ;
1603+ result = source . CompositionTarget . TransformFromDevice . Transform ( positionFromScreen ) ;
1604+ return true ;
1605+ }
1606+ catch
1607+ {
1608+ // DYN-9823: PointToScreen can throw when the visual is not connected to a PresentationSource
1609+ // (e.g. during layout, tab switch, or node deletion). Popup placement is non-critical,
1610+ // so just return false for any exception and let the caller handle it.
1611+ return false ;
1612+ }
16021613 }
16031614
16041615 private void ViewModel_RequestAutoCompletePopupPlacementTarget ( Window window , PortModel portModel , double spacing )
16051616 {
16061617 if ( portModel . PortType == PortType . Input )
16071618 {
16081619 var portView = inputPortControl . ItemContainerGenerator . ContainerFromIndex ( portModel . Index ) as FrameworkElement ;
1609- window . Top = PointToLocal ( 0 , 0 , portView ) . Y ;
1610- window . Left = PointToLocal ( 0 , 0 , this ) . X - window . Width - spacing ;
1620+ if ( TryPointToLocal ( 0 , 0 , portView , out var portTop ) && TryPointToLocal ( 0 , 0 , this , out var nodeLeft ) )
1621+ {
1622+ window . Top = portTop . Y ;
1623+ window . Left = nodeLeft . X - window . Width - spacing ;
1624+ }
16111625 }
16121626 else
16131627 {
16141628 var portView = outputPortControl . ItemContainerGenerator . ContainerFromIndex ( portModel . Index ) as FrameworkElement ;
1615- window . Top = PointToLocal ( 0 , 0 , portView ) . Y ;
1616- window . Left = PointToLocal ( ActualWidth , 0 , this ) . X + spacing ;
1629+ if ( TryPointToLocal ( 0 , 0 , portView , out var portTop ) && TryPointToLocal ( ActualWidth , 0 , this , out var nodeRight ) )
1630+ {
1631+ window . Top = portTop . Y ;
1632+ window . Left = nodeRight . X + spacing ;
1633+ }
16171634 }
16181635 }
16191636
16201637 private void ViewModel_RequestClusterAutoCompletePopupPlacementTarget ( Window window , double spacing )
16211638 {
1622- Point targetPoints = PointToLocal ( 0 , ActualHeight , this ) ;
1639+ if ( ! TryPointToLocal ( 0 , ActualHeight , this , out var targetPoints ) )
1640+ return ;
16231641 window . Left = Math . Clamp ( targetPoints . X ,
16241642 SystemParameters . VirtualScreenLeft ,
16251643 SystemParameters . VirtualScreenLeft + SystemParameters . VirtualScreenWidth - window . Width ) ;
0 commit comments