AdvancedHMI Software
General Category => Support Questions => Topic started by: DanieLoche on July 19, 2016, 11:14:35 AM
-
Hello,
It's almost a mix between a support question and a suggestion... but here I am. ^^
I noticed that one of the "bad" things with Visual Studio (and so with AdvancedHMI) is about the creation of a layer that will include different forms.
The biggest example for us is having in every form the buttons to navigate through the HMI : for now from what I saw we are forced to copy/paste every single thing that is common to multiple forms.
So I'm thinking about a way to avoid this issue.
The solution I know from Visual Studio is with Multiple-Document Interface (MDI).
So I'm trying to create a Main Form that will be the MDI-parent. And in it will be displayed the MDI-child wanted, following the ChangeFormButton I click on.
Sounds good, no ??
The issue is that for that I have to chance the way "ChangeToForm" method works. But there I'm having some issues, any help guys ? :)
I found that :
Dim f1 As Form
'* My.Forms has a property for each form in the Application
'* This is default instances of the forms
Dim p() As Reflection.PropertyInfo = My.Forms.GetType().GetProperties
'* Check to see if the name is a form in the list
While index < p.Length AndAlso p(index).Name <> m_FormToOpen.Name
index += 1
End While
If index < p.Length Then
f1 = DirectCast(p(index).GetValue(My.Forms, Nothing), Form)
f1.Show()
f1.BringToFront()
'* Keep going up the tree until we find the top level parent
pf = Parent
While (pf IsNot Nothing) AndAlso (Not (TypeOf (pf) Is Form))
If pf.Parent IsNot Nothing Then
pf = pf.Parent
Else
Exit While
End If
End While
'* Hide the form this event came from
'* It may be embedded in other containers
'*If it is the same form, then do not hide 04-aug-14
If pf IsNot Nothing AndAlso (f1 IsNot pf) Then
'* Delay hiding the previous form so that it transitions busy forms smoother
ht.Start()
End If
I suppose that I have to find a way to find the other MDI childs, to hide (?) them instead of looking for the parent.
Also I got an issue with the first part of the job : when I open a first MDI Child, either it is fully occupying the space I gave for it, but then I have the Form Border that appears for my main form ! Or the MDI Child is not maximized...
-
You might get a little help from this topic:
http://advancedhmi.com/forum/index.php?topic=325.msg3161#msg3161
-
I found a nice way to display that. :)
The first difficulty was to get this working with no Form Border eitheir in the Main Form and in the MDI Children.
The best I found is using the Dock property for the MDI Childs : Add the Event Form Load, and put something like :
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Dock = DockStyle.Fill
End Sub
Now I have to find how to change the ChangFormButton controls to get the following behavior :
- Show the indicated MDI child Form.
- Get the parent (will be main form)
- Get the others MDI Child and hide them (actually should be only 1 form)
-
So you want to be able to open up one form on multiple forms all in an MDI format?
If yes then read on.
This is in C# but i am positive it can be done in VB.net
YourTab.TabPages.Add(YourTabPage);
YourForm.Main msMain = new YourForm.Main();
msMain.TopLevel = false;
msMain.Dock = DockStyle.Fill;
Splitter.Controls.Add(msMain);
msMain.Show();
I used a split container to add the form as a control.
And to eliminate borders and stuff that can all be done in the form properties.
That is production code I use currently and it works perfect. I have a ShopStatus page that is shared with multiple tab's in an MDI project.
Let me know if you have any questions.
-
Thats what it would look like
-
You can create a MDI form by creating a Form (in this example named MDIForm1) and setting it's IsMdiContainer property to true
You can make child forms by:
1.) Setting the ControlBox property of the Form to false
2.) Adding the following into the "Child form's" designer.vb
<System.Diagnostics.DebuggerNonUserCode()> Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'This form is an MDI child.
'This code simulates the VB6 functionality of automatically
'loading and showing an MDI child's parent.
Me.MdiParent = MDIForm1
End Sub
3.) Add the following to the Form's Load event
Me.Visible = True
Me.Opacity = 0
Me.WindowState = FormWindowState.Maximized
Me.Opacity = 1
Sample project attached.
-
In Morgan's project, you could control opening and closing of the child forms from a single MenuStrip control (to substitute Panel and 2 buttons of the MainForm as well as button on each child form).
It would look like the attached picture and the code could look like this:
Public Class MDIForm1
Private Sub Child1ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles Child1ToolStripMenuItem.Click
If frmChild1.Visible Then frmChild1.Focus()
End Sub
Private Sub LoadToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LoadToolStripMenuItem.Click
If Not frmChild1.Visible Then frmChild1.Show()
End Sub
Private Sub CloseToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CloseToolStripMenuItem.Click
If frmChild1.Visible Then frmChild1.Close()
End Sub
Private Sub LoadToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles LoadToolStripMenuItem1.Click
If Not frmChild2.Visible Then frmChild2.Show()
End Sub
Private Sub CloseToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles CloseToolStripMenuItem1.Click
If frmChild2.Visible Then frmChild2.Close()
End Sub
Private Sub Child2ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles Child2ToolStripMenuItem.Click
If frmChild2.Visible Then frmChild2.Focus()
End Sub
End Class
-
Thanks a lot for the answers guys. :)
I had something nice working yesterday, with a MDI parent for the frame and the others forms as MDI Children.
Gave me something like that :
[MDI Project attached file]
I just tried Mikefly95's solution. Seems very smooth ! I didn't know that it was possible to add forms to the splitcontainers. :)
This solution gave me almost the same thing, but without the borders between the main form and the children :
[Split container Project attached file]
All in all, I'm using the ChangeFormButtons to switch from a form to another (buttons located on the main form as you can see attached).
I had to change the code to work for both solutions.
For mine, I added that to the open form function :
If f1.ShowInTaskbar = False Then
f1.MdiParent = pf
End If
If I want other forms to be in fullscreen (ex the Login Page), then I set its ShowInTaskbar property to True.
So if it's not the case, I put it as an MDI Child before showing it.
The hardest part is to manage the hidding of the other forms :
Dim pf As Object
Dim f1 As Form
Private Sub HideForm(ByVal e As Object, ByVal ef As EventArgs)
e.stop()
ht.Enabled = False
If pf IsNot Nothing Then
If f1.ShowInTaskbar Then
pf.Hide()
Else
For Each item As Form In pf.MdiChildren
If item IsNot f1 Then
item.Hide()
End If
Next
End If
End If
End Sub
pf is the main form with the button.
f1 the new form to show. So I go through every MDI child and hide them except the newest one (f1).
But now when it comes to the SplitContainer solution, I don't know how I could go through every form to hide them has I no more have an MDIchild list...
-
Should be able to close any forms in your split container before opening the form you want.
When you click your button to open a new form roll this code first
For each f as form in YourSplitContainer
f.close() or f.Hide()
next
And then your code to open your new form
I currently do not have any VB projects to test this on but i do use similar code to empty text boxes after someone completes a form.
let me know if this helps or if you need another solution.
Mike
-
Sounds like very hardcoded IMO, but yes it works. ^^
-
Yea i do a lot of hard coding all day every day!! Just glad it worked and let me know if you have any other issues!!
Mike