Page 2 of 2

Re: Embedding a form in a form

Posted: Mon Oct 23, 2017 7:23 am
by EnergySmithe
That is brilliant, thank you JV!

Re: Embedding a form in a form

Posted: Mon Oct 23, 2017 1:25 pm
by EnergySmithe
So while I am able to attach the form as an MDI child, I am still running into code behind control referencing/scoping issues. If I create a simple form with a label and button and put $label1.text = "Hello World!" as the click event for the button, when I load it as an MDI child and click the button, it cannot find $label1. In the MDI Parent if I add a label docked to the top and name it $label1, then when I click the button in the MDI Child, the code succeeds, but it sets the text in the MDI parents version of $label1. So change the code in the child form obtain a reference from the controls collection the button resides on? No easy answers with this. Wish I could switch to VS but not an option in this case.

Re: Embedding a form in a form

Posted: Mon Oct 23, 2017 2:04 pm
by jvierra
This is how child forms work in PowerShell. You will need to invoke the control from an event context. Some controls and settings work as expected but others are handled by the parent. Also the parent is the message loop and since it is a dialog there is only one message loop.

Here is an example of how to load and manage a child form. Look at the child and see what changes were made to make it work. You can launch multiple copies of the form an each is completely independent.

Re: Embedding a form in a form

Posted: Mon Oct 23, 2017 2:28 pm
by EnergySmithe
jvierra, thank you for this excellent example, this is really helpful!

Re: Embedding a form in a form

Posted: Tue Oct 24, 2017 12:55 pm
by jvierra
Here is another bunch of tricks you can do with an MDI Form.

Re: Embedding a form in a form

Posted: Tue Oct 24, 2017 2:55 pm
by EnergySmithe
Thank you again jvierra, this is very helpful!

Re: Embedding a form in a form

Posted: Tue Oct 24, 2017 3:34 pm
by jvierra
Her eis a new copy as the last one had a bad bit of debug code left in it. The "Window" item doesn't work. This one does.

Re: Embedding a form in a form

Posted: Wed Oct 25, 2017 5:05 am
by jvierra
Here is the next demo version that shows how to load a form from a PS1 file that has been exported from a PSF form. (using deploy\export to file).

The next step is to move this to a PSS project and load from in-memory form function. The code will need to be generalized and we will load all functions during startup so they can be re-used as needed. In MDI a form can be saved and re-displayed with data. This can allow us to preset a forms data for reuse and for other useful things.

In each form we need to detect when certain events are being used and alter the call because, like with the "Close" event the method on the parent needs to be called.

In a compiled C# program this is done with delegates. It is convenient that PowerShell gives us a much simper method for doing this. If we had to use delegates then the threading issue would be a problem.

Eventually I want to show how to load a form into a runspace and have it usable within an MDI. This allows us to run a separate form that manages a single job with an independent GUI. Examples have been created that use this to create a simple form with a progress bar that tracks a job. It is also useful for independently displaying a log file that can be controlled and written to from all forms in a project.

Be sure to place both files into the same folder.

Re: Embedding a form in a form

Posted: Wed Oct 25, 2017 5:49 am
by jvierra
I should probably raise this warning again. Even though you are running in an independent child form and the child is launched with the "Show()" method it is still a child of a modal dialog started with "ShowDialog()". There is till only one thread that handles all event dispatches. This thread will block on a child the same as it does on a basic form. There is now way around this with PowerShell because PS has only one thread. All events in a child need t be designed with this in mind. If you want to not block you will have to use a JobTracker in the child. Catch 22.5 --- the timer events will still be handled by the parent form. This can be managed but you need to keep it in mind.

Above I mentioned using a runspace for the child form. This would not block and can provide complete child independence but forces as to use a synchash for communication between parent and child and presents some other cute issues that have to be programmed to.