private/output/Add-ArrayCellPopupHandler.ps1
|
function Add-ArrayCellPopupHandler { <# .SYNOPSIS Adds click handler to DataGrid for expanding array cells in a popup. Shows items in a scrollable list instead of the raw type string. #> [CmdletBinding()] param( [Parameter(Mandatory)] [System.Windows.Controls.DataGrid]$DataGrid ) $DataGrid.Add_PreviewMouseLeftButtonDown({ param($sender, $eventArgs) if ($script:currentArrayPopup -and $script:currentArrayPopup.IsOpen) { $script:currentArrayPopup.IsOpen = $false $script:currentArrayPopup = $null } # Only italic TextBlocks with array data in Tag get popups $source = $eventArgs.OriginalSource if ($source -isnot [System.Windows.Controls.TextBlock]) { return } $textBlock = $source if ($textBlock.FontStyle -ne [System.Windows.FontStyles]::Italic) { return } if ($null -eq $textBlock.Tag) { return } $arrayValue = $textBlock.Tag # Dictionaries have their own popup if ($arrayValue -is [string] -or $arrayValue -is [System.Collections.IDictionary]) { return } # Refuses a one pass reader without reading it, and an empty list, whose popup would be a header and a copy button over just an empty string if (![PsUi.ValueKind]::IsExpandable($arrayValue)) { return } $popupColors = Get-ThemeColors $popup = [System.Windows.Controls.Primitives.Popup]@{ StaysOpen = $false AllowsTransparency = $true Placement = 'Mouse' VerticalOffset = -20 HorizontalOffset = -10 } $popupBorder = [System.Windows.Controls.Border]@{ Background = ConvertTo-UiBrush $popupColors.ControlBg BorderBrush = ConvertTo-UiBrush $popupColors.Border BorderThickness = [System.Windows.Thickness]::new(1) CornerRadius = [System.Windows.CornerRadius]::new(4) Padding = [System.Windows.Thickness]::new(12) MaxWidth = 400 MaxHeight = 300 } $popupBorder.Add_MouseLeave({ param($sender, $eventArgs) if ($script:currentArrayPopup) { $script:currentArrayPopup.IsOpen = $false $script:currentArrayPopup = $null } }) $shadow = [System.Windows.Media.Effects.DropShadowEffect]@{ BlurRadius = 10 ShadowDepth = 3 Opacity = 0.3 } $popupBorder.Effect = $shadow # With Auto the panel measures at infinite width, and the TextWrapping on every line below never gets a width to wrap at $scrollViewer = [System.Windows.Controls.ScrollViewer]@{ VerticalScrollBarVisibility = 'Auto' HorizontalScrollBarVisibility = 'Disabled' } $stackPanel = [System.Windows.Controls.StackPanel]::new() $copyHeader = New-UiPopupCopyHeader -Colors $popupColors $headerRow = $copyHeader.Panel $header = $copyHeader.Title $copyState = $copyHeader.State $items = @($arrayValue) $header.Text = if ($items.Count -eq 1) { '1 item:' } else { "$($items.Count) items:" } [void]$stackPanel.Children.Add($headerRow) $copyLines = [System.Collections.Generic.List[string]]::new() foreach ($item in $items) { # Each line reads the way a cell would show it, so a list of hashtables lists @{a=1} rather than a type name per line. $line = "$(ConvertTo-DisplayValue -Value $item)" $copyLines.Add($line) $itemText = [System.Windows.Controls.TextBlock]@{ Text = $line TextWrapping = 'Wrap' Margin = [System.Windows.Thickness]::new(0, 2, 0, 2) Foreground = ConvertTo-UiBrush $popupColors.ControlFg } [void]$stackPanel.Children.Add($itemText) } $copyState.Text = $copyLines -join [Environment]::NewLine $scrollViewer.Content = $stackPanel $popupBorder.Child = $scrollViewer $popup.Child = $popupBorder $script:currentArrayPopup = $popup $popup.IsOpen = $true }.GetNewClosure()) } |