Embedding a form in a form

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
User avatar
EnergySmithe
Posts: 9
Joined: Wed Jul 08, 2015 8:50 am

Re: Embedding a form in a form

Post by EnergySmithe » Mon Oct 23, 2017 7:23 am

That is brilliant, thank you JV!

User avatar
EnergySmithe
Posts: 9
Joined: Wed Jul 08, 2015 8:50 am

Re: Embedding a form in a form

Post by EnergySmithe » Mon Oct 23, 2017 1:25 pm

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.

jvierra
Posts: 14021
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Embedding a form in a form

Post by jvierra » Mon Oct 23, 2017 2:04 pm

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.
Attachments
Demo-MDIAutoLoad.psf
(26.44 KiB) Downloaded 48 times

User avatar
EnergySmithe
Posts: 9
Joined: Wed Jul 08, 2015 8:50 am

Re: Embedding a form in a form

Post by EnergySmithe » Mon Oct 23, 2017 2:28 pm

jvierra, thank you for this excellent example, this is really helpful!

jvierra
Posts: 14021
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Embedding a form in a form

Post by jvierra » Tue Oct 24, 2017 12:55 pm

Here is another bunch of tricks you can do with an MDI Form.
Attachments
Demo-MDIAutoLoad.psf
(36.45 KiB) Downloaded 40 times

User avatar
EnergySmithe
Posts: 9
Joined: Wed Jul 08, 2015 8:50 am

Re: Embedding a form in a form

Post by EnergySmithe » Tue Oct 24, 2017 2:55 pm

Thank you again jvierra, this is very helpful!

jvierra
Posts: 14021
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Embedding a form in a form

Post by jvierra » Tue Oct 24, 2017 3:34 pm

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.
Attachments
Demo-MDIAutoLoad5.psf
(35.43 KiB) Downloaded 39 times

jvierra
Posts: 14021
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Embedding a form in a form

Post by jvierra » Wed Oct 25, 2017 5:05 am

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.
Attachments
MDIChildTest.psf
(18.14 KiB) Downloaded 46 times
Demo-MDIAutoLoad6.psf
(56.4 KiB) Downloaded 44 times

jvierra
Posts: 14021
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Embedding a form in a form

Post by jvierra » Wed Oct 25, 2017 5:49 am

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.

Locked