前提・実現したいこと
メインフォーム単体で機能が成り立っているところに
入力補助のために補助フォームを作りたいと思ったのですが
メインフォームだけで機能としては成り立っているので
出来ればメインフォームでモジュールには補助フォームを管理したくありません。
自分なりに考えて
指定イベントの発生時に自身のインスタンスに保存されているスクリプトブロック
を実行する
クラスEventHook
を作ってみたのですが
EventHook
の Run
メソッドを実行したときに
事前に渡したスクリプトブロック内の$This
が
EventHook
がps1に書かれているときは
正常に EventHook
のインスタンス になるのですが
psm1に書かれているときは
イベントの発生源のオブジェクト
になってしまい EventHook
のプロパティにアクセスできません...
どうしたらモジュールにしても正常に実行できるようになるのでしょうか?
教えて頂きたいです。
別の方法でも構いません。
お願い致します。
該当のソースコード
powershell
1# EventHook.psm1 2 3Using NameSpace System.Collections.Generic 4Using NameSpace System.Windows.Forms 5Using NameSpace System.Drawing 6Using NameSpace System.Collections.Specialized 7 8 9<# 10 柔軟なイベント実行を補助します。 11#> 12class EventHook 13{ 14 static [OrderedDictionary] $EventHooks = [OrderedDictionary]::new() 15 [string] $Guid 16 [Object] $Hook 17 [scriptblock] $RunBlock 18 [Object] $Argument 19 20 # コンストラクタの共通の処理です。 21 hidden [void] Common ([Object] $HookObject, [String] $MethodName, [ScriptBlock] $Block) 22 { 23 $This.Guid = New-Guid 24 [EventHook]::EventHooks[$This.Guid] = $This 25 $This.Hook = $HookObject 26 $This.RunBlock = $Block 27 28 [scriptblock] $EventBlock = [scriptblock]::Create('[{0}]::SearchRun("{1}", $args)' -f @($This.Gettype().Name,$This.Guid)) 29 $HookObject.$MethodName($EventBlock) 30 } 31 32 # コンストラクタ 33 EventHook ([Object] $HookObject, [String] $MethodName, [ScriptBlock] $Block) 34 { 35 $This.Common([Object] $HookObject, [String] $MethodName, [ScriptBlock] $Block) 36 } 37 38 # コンストラクタ 39 EventHook ([Object] $HookObject, [String] $MethodName, [ScriptBlock] $Block, [Object] $Set_Argument) 40 { 41 $This.Common([Object] $HookObject, [String] $MethodName, [ScriptBlock] $Block) 42 $This.Argument = $Set_Argument 43 } 44 45 # 保存されているスクリプトブロックの実行 46 [Void] Run ([Object[]] $Set_Argument) 47 { 48 Write-Host "Run : $($This.GetType().name)" 49 if ($Set_Argument.Count -gt 0) 50 { 51 $This.RunBlock.Invoke($Set_Argument) 52 } 53 else 54 { 55 $This.RunBlock.Invoke() 56 } 57 } 58 59 # GUIDが一致するインスタンスを探してRunを実行する 60 static [Void] SearchRun ([String] $GUID, [Object[]] $Set_Argument) 61 { 62 [EventHook] $Obj = [EventHook]::EventHooks[$GUID] 63 64 if ($obj -ne $null) 65 { 66 $obj.Run($Set_Argument) 67 } 68 69 } 70 71}
powershell
1# テスト.ps1 2 3Using NameSpace System 4Using NameSpace System.Collections.Generic 5Using NameSpace System.Windows.Forms 6Using NameSpace System.Collections.Specialized 7 8 9Using Module .\EventHook.psm1 10 11Add-type -AssemblyName System.WIndows.Forms 12 13 14$Form = [Form]::new() 15 16$text = [TextBox]::new() 17 18$Form.Controls.Add($text) 19 20[EventHook]::New($Form,"Add_Click",{ 21 22<# 23 EventHook が $Thisになってほしいのに 24 EventHookがpsm1 に書かれていると 25 イベント発生源の オブジェクトが $Thisになる 26#> 27 Write-Host "Block : $($This.Gettype().name)" 28}) 29 30$Form.showDialog()
試したこと
Run メソッド 内で スクリプトブロックを実行する前に
GetNewClosure()
したりしてみましたがだめでした。
補足情報(FW/ツールのバージョンなど)
powershell v5
Win 10
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/25 14:14
2019/03/26 01:03
2019/03/26 01:29 編集
2019/03/26 01:43
2019/03/26 12:41
2019/03/27 00:45