PoshWPF.psm1
Add-Type -AssemblyName PresentationFramework,PresentationCore,WindowsBase Function New-WPFWindow { Param( [Parameter(Mandatory=$true, Position=0, HelpMessage="XAML code of UI")] [ValidateNotNullOrEmpty()] [xml]$xaml ) $FormattedXAML = Format-WPFXAML -xaml $xaml $Global:PoshWPFHashTable = [HashTable]::Synchronized(@{}) $Global:PoshWPFHashTable.Host = $Host $Global:PoshWPFHashTable.xaml = $FormattedXAML $Global:PoshWPFHashTable.Actions = New-Object System.Collections.ArrayList $Global:PoshWPFHashTable.ActionsMutex = New-Object System.Threading.Mutex($false, 'ActionsMutex') $Global:PoshWPFHashTable.WindowShown = $false $Global:PoshWPFHashTable.WindowControls = @{} $Global:PoshWPFHashTable.ScriptDirectory = $PSScriptRoot $Runspace = [RunspaceFactory]::CreateRunspace() $Runspace.ApartmentState = 'STA' $Runspace.ThreadOptions = "ReuseThread" $Runspace.Open() $Runspace.SessionStateProxy.SetVariable('PoshWPFHashTable', $Global:PoshWPFHashTable) $PS = [PowerShell]::Create() $PS.Runspace = $Runspace $null = $PS.AddScript({ $ScriptDirectory = $PoshWPFHashTable.ScriptDirectory . "$ScriptDirectory\PoshWPF-UI-Code.ps1" [xml]$xaml = $PoshWPFHashTable.xaml Show-WPFWindow -xaml $xaml }) $Global:PoshWPFHashTable.Handle = $PS.BeginInvoke() $Global:PoshWPFHashTable.Runspace = $Runspace while(!$Global:PoshWPFHashTable.WindowShown) { Start-Sleep -Milliseconds 10 } } Function Format-WPFXAML { param( [xml]$xaml ) if($xaml.Window) { $Attributes = $xaml.Window.Attributes $AttributesToRemove = @() foreach($Attribute in $Attributes) { Switch($Attribute.LocalName) { 'Class' { $AttributesToRemove += @($Attribute.Name) } 'Local' { $AttributesToRemove += @($Attribute.Name) } 'Ignorable' { $AttributesToRemove += @($Attribute.Name) } } } foreach($Attribute in $AttributesToRemove){ $xaml.Window.RemoveAttribute($Attribute) } $xaml } else { Throw 'No window object!' } } Function Add-WPFAction { param( [scriptblock]$ScriptBlock ) $null = $Global:PoshWPFHashTable.ActionsMutex.WaitOne() $null = $Global:PoshWPFHashTable.Actions.Add($ScriptBlock) $null = $Global:PoshWPFHashTable.ActionsMutex.ReleaseMutex() } Function Invoke-WPFAction { param( [ScriptBlock]$Action ) $Global:PoshWPFHashTable.WindowControls.Window.Dispatcher.Invoke([action]$Action, 'Normal') } Function Get-WPFControl { Param( [string]$ControlName, [string]$PropertyName ) if($ControlName -ne 'Window') { $ControlName = "Window_$($ControlName)" } $Control = $Global:PoshWPFHashTable.WindowControls[$ControlName] if($null -ne $Control) { if([string]::IsNullOrEmpty($PropertyName)) { $PropertyHash = @{} $ControlProperties = ($Control | Get-Member -MemberType Property).Name foreach($ControlProperty in $ControlProperties) { $PropertyHash[$ControlProperty] = $Control."$($ControlProperty)" } $PropertyHash } else { $Control."$PropertyName" } } else { Throw 'Control not found!' } } Function Set-WPFControl { Param( [string]$ControlName, [string]$PropertyName, [object]$Value ) if($ControlName -ne 'Window') { $ControlName = "Window_$ControlName" } $Guid = (New-Guid).Guid $Global:PoshWPFHashTable[$guid] = $Value $strScriptBlock = "`$PoshWPFHashTable.WindowControls['$($ControlName)'].$($PropertyName) = `$PoshWPFHashTable['$guid'];" + ` "`$null = `$PoshWPFHashTable.Remove('$guid')" $ScriptBlock = [ScriptBlock]::Create($strScriptBlock) Invoke-WPFAction -Action $ScriptBlock } Function New-WPFEvent { Param( [string]$ControlName, [string]$EventName, [scriptblock]$Action ) if($ControlName -ne 'Window') { $ControlName = "Window_$ControlName" } $WinControls = $Global:PoshWPFHashTable.WindowControls $null = Register-ObjectEvent -InputObject $WinControls[$ControlName] -EventName 'Click' -Action $Action } |