WPF/Show-Window.ps1
function Show-Window { <# .Synopsis Show-Window shows a WPF control within a window, and is used by the -Show Parameter of all commands within WPK .Description Show-Window displays a control within a window and adds several resources to the window to make several scenarios (like timed events or reusable scripts) easier to accomplish within the WPF control. .Parameter Control The UI Element to display within the window .Parameter Xaml The xaml to display within the window .Parameter WindowProperty Any additional properties the window should have. Use the values of this dictionary as you would parameters to New-Window .Parameter OutputWindowFirst Outputs the window object just before it is displayed. This is useful when you need to interact with the window from outside of the thread displaying it. .Example New-Label "Hello World" | Show-Window #> [CmdletBinding(DefaultParameterSetName="Window")] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Control", Position=0)] [Windows.Media.Visual] $Control, [Parameter(Mandatory=$true,ParameterSetName="Xaml",ValueFromPipeline=$true,Position=0)] [xml] $Xaml, [Parameter(ParameterSetName='Window',Mandatory=$true,ValueFromPipeline=$true,Position=0)] [Windows.Window] $Window, [Hashtable] $WindowProperty = @{}, [Parameter(Mandatory=$true,ParameterSetName="ScriptBlock",ValueFromPipeline=$true,Position=0)] [ScriptBlock] $ScriptBlock, [Parameter(ParameterSetName="ScriptBlock")] [Hashtable] $ScriptParameter = @{}, [Switch] $OutputWindowFirst, [Parameter(ParameterSetName="ScriptBlock")] [Parameter(ParameterSetName="Xaml")] [Alias('Async')] [switch]$AsJob ) process { try { $windowProperty += @{ SizeToContent="WidthAndHeight" } } catch { Write-Debug ($_ | Out-String) } switch ($psCmdlet.ParameterSetName) { Control { $window = New-Window Set-Property -inputObject $window -property $WindowProperty $window.Content = $Control $instanceName = $control.Name $specificWindowTitle = $Control.GetValue([Windows.Window]::TitleProperty) if ($specificWindowTitle) { $Window.Title = $specificWindowTitle } elseif ($instanceName) { $Window.Title = $instanceName } else { $controlName = $Control.GetValue([ShowUI.ShowUISetting]::ControlNameProperty) if ($controlName) { $Window.Title = $controlName } } } Xaml { if ($AsJob) { Start-WPFJob -Parameter @{ Xaml = $xaml WindowProperty = $windowProperty } -ScriptBlock { param($Xaml, $windowProperty) $window = New-Window Set-Property -inputObject $window -property $WindowProperty $strWrite = New-Object IO.StringWriter $xaml.Save($strWrite) $Control = [windows.Markup.XamlReader]::Parse("$strWrite") $window.Content = $Control Show-Window -Window $window } return } else { $window = New-Window Set-Property -inputObject $window -property $WindowProperty $strWrite = New-Object IO.StringWriter $xaml.Save($strWrite) $Control = [windows.Markup.XamlReader]::Parse("$strWrite") $window.Content = $Control } } ScriptBlock { if ($AsJob) { Start-WPFJob -ScriptBlock { param($ScriptBlock, $scriptParameter = @{}, $windowProperty) $window = New-Window $exception = $null $results = . $ScriptBlock @scriptParameter 2>&1 $errors = $results | Where-Object { $_ -is [Management.Automation.ErrorRecord] } if ($errors) { $window.Content = $errors | Out-String try { $windowProperty += @{ FontFamily="Consolas" Foreground='Red' } } catch { Write-Debug ($_ | Out-String) } } else { if ($results -is [Windows.Media.Visual]) { $window.Content = $results } else { $window.Content = $results | Out-String try { $windowProperty += @{ FontFamily="Consolas" } } catch { Write-Debug ($_ | Out-String) } } } Set-Property -inputObject $window -property $WindowProperty Show-Window -Window $window } -Parameter @{ ScriptBlock = $ScriptBlock ScriptBlockParameter = $ScriptBlockParameter WindowProperty = $windowProperty } return } else { $window = New-Window $results = & $ScriptBlock @scriptParameter if ($results -is [Windows.Media.Visual]) { $window.Content = $results } else { $window.Content = $results | Out-String } try { $windowProperty += @{ FontFamily="Consolas" } } catch { Write-Debug ($_ | Out-String) } Set-Property -inputObject $window -property $WindowProperty } } } $Window.Resources.Timers = New-Object Collections.Generic.Dictionary["string,Windows.Threading.DispatcherTimer"] $Window.Resources.TemporaryControls = @{} $Window.Resources.Scripts = New-Object Collections.Generic.Dictionary["string,ScriptBlock"] $Window.add_Closing({ foreach ($timer in $this.Resources.Timers.Values) { if (-not $timer) { continue } $null = $timer.Stop() } $this | Get-ChildControl -PeekIntoNestedControl | Where-Object { $_.Resources.EventHandlers } | ForEach-Object { $object = $_ $handlerNames = @($_.Resources.EventHandlers.Keys) foreach ($handler in $handlerNames){ $object."remove_$($handler.Substring(3))".Invoke($object.Resources.EventHandlers[$handler]) $null = $object.Resources.EventHandlers.Remove($handler) } $object.Resources.Remove("EventHandlers") } }) if ($outputWindowFirst) { $Window } $null = $Window.ShowDialog() if ($Control.Tag -ne $null) { $Control.Tag } elseif ($Window.Tag -ne $null) { $Window.Tag } else { if ($Control.SelectedItems) { $Control.SelectedItems } if ($Control.Text) { $Control.Text } if ($Control.IsChecked) { $Control.IsChecked } } return } } Set-Alias Show-BootsWindow Show-Window Set-Alias Show-UI Show-Window |