Event Handling & Scope

I discovered whilst attempting to write an event handler for the DownloadFileCompleted event of System.Net.WebClient in a WinForms script (via PrimalForms) that it was better to use the add_DownloadProgressChanged method of the object to add the event handler than adding it through the Register-ObjectEvent.  It appears whilst running a form that event handling in Register-ObjectEvent didnt fire correctly. 

In other words,instead of using :-


Register-ObjectEvent -InputObject $webclient -EventName DownloadFilecompleted -SourceIdentifier Webclient.DownloadFilecompleted -Action {blablabla}

It was better for me to do


$webClient_DownloadFileCompleted = {blablabla}

In any case, using the add_DownloadProgressChanged method also appeared to extend the scope automatically in the $webClient_DownloadFileCompleted scriptblock.  i could now update other controls in the form (such as changing the text of a label)  I left this part of the code happy!

This leads onto my question though.  Can i replicate this type behaviour for other any other type of event that might not have that type of add_ method? i.e. have working event handling scriptblocks in a form and have access to all the objects in the form.

Hope i've explained this well!





  • PowerShell script in a WinForm is certainly different than simply running at a script at the console. As you've discovered there is some trial and error and sometimes a happy discovery about what will work and what won't.  I don't think I can make a blanket statement regarding your technique. If it was me, I'd simply take it on a case by case basis. Try it and see.

  • Hi Jeff, thanks for the quick reply.

    An hour or so ago i found a function (written by Brett Ernst), which i've tested with  a couple of external .net assemblies that dont have an "add" method for the events in them, and it works great.

    function Add-Handler([object]$target,[string]$eventName,$script)
        $evt = $target.GetType().GetEvent($eventName)
        $eh = [EventHandler]$script
        $del = [Delegate]::CreateDelegate($evt.EventHandlerType,$eh.Target,$eh.Method)


    This gives me sufficient scope to allow reading and changing of the objects on the winform without having to use -messagedata or $global:xxxx variables with register-objectevent and fits in nicely with the rest of the code of my ps winforms project.