-
Notifications
You must be signed in to change notification settings - Fork 2
/
Add-EventHandler.ps1
102 lines (89 loc) · 3.18 KB
/
Add-EventHandler.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
function Add-EventHandler {
<#
.Synopsis
Adds an event handler to an object
.Description
Adds an event handler to an object. If the object has a
resource dictionary, it will add an eventhandlers
hashtable to that object and it will store the event handler,
so it can be removed later.
.Example
$window = New-Window
$window | Add-EventHandler Loaded { $this.Top = 100 }
.Parameter Object
The Object to add an event handler to
.Parameter EventName
The name of the event (i.e. Loaded)
.Parameter Handler
The script block that will handle the event
.Parameter SourceType
For RoutedEvents, the type that originates the event
.Parameter PassThru
If this is set, the delegate that is added to the object will
be returned from the function.
#>
param(
[Parameter(ValueFromPipeline=$true, Mandatory=$true, Position = 0, ParameterSetName="SimpleEvents")]
[ValidateNotNull()]
[Alias("Object")]
$InputObject,
[Parameter(Mandatory=$true, Position=1)]
[String]
$EventName,
[Parameter(Mandatory=$true, Position=2)]
[ScriptBlock]
$Handler,
[Parameter(Mandatory=$false)]
[String]
$SourceType,
[Switch]
$PassThru
)
process {
if($SourceType) {
$Type = $SourceType -as [Type]
if(!$Type) {
$Type = (Get-Command $SourceType).OutputType[0].Type
}
if(!$Type) {
Write-Error "Can't determine type from '$SourceType', you should pass either a Type or the name of a ShowUI command that outputs a UI Element. We will try the InputObject(s)"
$Type = $InputObject.GetType()
}
} else {
$Type = $InputObject.GetType()
}
if ($eventName.StartsWith("On_")) {
$eventName = $eventName.Substring(3)
}
$Event = $Type.GetEvent($EventName, [Reflection.BindingFlags]"IgnoreCase, Public, Instance")
if (-not $Event) {
Write-Error "Handler $EventName does not exist on $InputObject"
return
}
$realHandler = ([ScriptBlock]::Create(@"
`$eventName = 'On_$eventName';
`$parent = . Get-ParentControl
. Initialize-EventHandler -parent `$parent
`$ErrorActionPreference = [Management.Automation.ActionPreference]::Stop
$Handler
trap {
. Write-WPFError `$_
continue
}
"@)) -as $event.EventHandlerType
if($realHandler -is [System.Windows.RoutedEventHandler] -and $Type::"${EventName}Event" ) {
$InputObject.AddHandler( $Type::"${EventName}Event", $realHandler )
} else {
if ($InputObject.Resources) {
if (-not $InputObject.Resources.EventHandlers) {
$InputObject.Resources.EventHandlers = @{}
}
$InputObject.Resources.EventHandlers."On_$EventName" = $realHandler
}
$event.AddEventHandler($InputObject, $realHandler)
}
if ($passThru) {
$RealHandler
}
}
}