Author Topic: Forms layout with MainMenu Buttons  (Read 1720 times)

boldive

  • Newbie
  • *
  • Posts: 33
    • View Profile
Forms layout with MainMenu Buttons
« on: September 28, 2018, 08:15:02 AM »
Hello everyone. I have started to make an application to replace 10" PanelView Plus. Using VisualStudio 2017 Community Edition on Windows 10 Enterp.
First try is not to use any code. So, simply follow instructions:
- In Solution Explorer, right click the AdvancedHMI project and select Properties
- Under the application tab change the Startup Form to MainMenu

You will now create new forms. Be sure to set the FormBorderStyle to None for all forms. After creating additional forms and Building the project, you can now add menu buttons for them:
- In Solution Explorer, expand down the AdvancedHMI project, then expand down to FormChangeControls\MainMenuDriven
- Double the MainMenu.vb to open in Design View
- From the Toolbox add a MainMenuButton for each new form
- Set the FormToOpen property
- You can also set the OpenOnStartup property for one button to indicate the default startup form

I did. Made MainMenu as a global menu. Zone1 calls submenu (another form just beside MainForm on layout) and few forms with actual information on the screens called from submenu form. As I understood MainMenuButtons work from MainMenu form only. They don't work on other forms. In my case on other forms these buttons don't see my other forms to call. Forms are visible to call from the MainMenu form only.

Compile, build and run it. It works. However it works in weird way.
Main menu form loads. In properties of button Zone1 (MainMenuButton) I call submenu with the flag OpenOnStartup: True.
OpenOnStartup doesn't work. Only MainMenu form is opens on Startup. Well, I click on Zone1 and submenu form loads beside mainmenu form on the right. Exactly how it supposed to be. Not bad. Now it is time to call 3rd form just beside submenu form on the right.
On SubMenu form I use FormChangeButton. Click on it and form with actual information from PLC is opens just beside submenu form on the right. Good! However my submenu form is not visible and I see a gap between MainMenu form and last open form.
Then I made another information form with the same properties and location as first.
Ok, will go further. I call my second information screen from the second MainManuButton on the MainMenu form. It works. Information form opens, but opens just beside MainMenu, not according to coordinates in the properties. Hm... I call second information screen from another FormChangeButton ot the Submenu form and it opens just beside MainMenu form, not according to position coordinates. So, two my information forms have identical properties in location coordinates but their position on the screen is different.

Even more. On the task bar I see every open form as a separate window, not as one application. How to deal with it? Use MDI ?

It seems like MainMenuButton closes all forms except MainMenu form and then opens form on call. What is the right way to manipulate between forms to keep some of them open (submenu for example)?

Also, I have noticed that there is a small problem with form size/scale. For some reason if form size 150x700 pixels on the screen it can be shown with ~95% scale. All my forms in properties have fixes size in pixels with start position flag: manual. AutoScaleMode value is : Inherit.

Project can be downloaded from Google Drive:
https://drive.google.com/file/d/19Z4MppSJ1mU_UZWTels2f-sY1MkGPVos/view?usp=sharing

Thanks

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5271
    • View Profile
    • AdvancedHMI
Re: Forms layout with MainMenu Buttons
« Reply #1 on: September 28, 2018, 09:05:54 AM »
The MainMenu and MainMenuButton is designed only for a Main Menu. Subs menus get a little more tricky.

I did a project with sub-menus and was able to do the project without the need to write code, but it was less than ideal. The way I did it was to add a panel to the form and put the FormChangeButtons of the sub-menu in the panel. This was the sub menu. It was then copied to every form. The result was the MainMenu had a button to get to the top level of the sub-menu controlled forms. Then each form switch to the sub-items.

The big drawback to this was the times a new button needed to added or changed on the sub-menu. After the change, then panel had to be copied and pasted to every form with that sub-menu.

boldive

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Forms layout with MainMenu Buttons
« Reply #2 on: September 28, 2018, 06:18:35 PM »
Thank you Archie for explanation. I will play with panels on the form.

Any words about OpenOnStartup: True? For some reason it doesn't work.

Thanks1

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5271
    • View Profile
    • AdvancedHMI
Re: Forms layout with MainMenu Buttons
« Reply #3 on: September 28, 2018, 08:26:37 PM »
I did a quick test and the OpenOnStartup worked as expected:

- Started with a new project
- In project properties I changed Startup Form to Mainmenu
- Opened the MainMenu form that had one MainMenuButton that had FormToOpen set to MainMenu
- Added another MainMenuButton to the MainMenu form and set FormToOpen to Page2

Started the application and the MainForm opened

- Back in Design mode, I opened MainMenu
- This time I set the Page 2 button OpenOnStartup to True
- Then on MainForm button I set OpenOnStartup to Fasle

Started the application and Page 2 opened.

boldive

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Forms layout with MainMenu Buttons
« Reply #4 on: September 30, 2018, 04:15:57 PM »
Well, it didn't work in my case. To make it running I had to do code programming. First to add CheckContainerControlsForOpenOnStartup
Code: [Select]
    Private Sub CheckContainerControlsForOpenOnStartup(ByVal container As Control)
        Dim index As Integer
        While index < container.Controls.Count
            ' If TypeOf container.Controls(index) Is Panel Then
            If container.Controls(index).HasChildren Then
                CheckContainerControlsForOpenOnStartup(container.Controls(index))
            Else

                If TypeOf container.Controls(index) Is MainMenuButton Then
                    If DirectCast(container.Controls(index), MainMenuButton).OpenOnStartup Then
                        DirectCast(container.Controls(index), MainMenuButton).PerformClick()
                        Exit While
                    End If
                End If
            End If

            index += 1
        End While
    End Sub

Then insert it into MainMenuLoad

Code: [Select]
    Private Sub _0000_MainMenu_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CheckContainerControlsForOpenOnStartup(Me)
    End Sub

Could you please confirm that this coding is a "must be" into a MainManu form to allow flag OpenOnStartup to be functional ?

Another question is about MainMenuButton color control.
I am using your LargePressHMIonPanelPC as a sample to follow in my design.
You have function SetButtonColor to apply default colors for MainMenuButton
Code: [Select]
   '* Set all buttons to non-selected
    Private Sub SetButtonColor(ByVal container As Control)
        Dim index As Integer
        While index < container.Controls.Count
            ' If TypeOf container.Controls(index) Is Panel Then
            If container.Controls(index).HasChildren Then
                CheckContainerControlsForOpenOnStartup(container.Controls(index))
            Else
                If TypeOf container.Controls(index) Is MainMenuButton Then
                    container.Controls(index).BackColor = Color.Black
                    container.Controls(index).ForeColor = Color.White
                End If
            End If

            index += 1
        End While
    End Sub

 and using this function on the button click event

Code: [Select]
    Private Sub FormChangeButton1_Click(sender As Object, e As EventArgs) Handles FormChangeButton1.Click, FormChangeButton2.Click, FormChangeButton3.Click, FormChangeButton4.Click
        For i = 0 To Controls.Count - 1
            SetButtonColor(Controls(i))
        Next

        Dim b As MainMenuButton = DirectCast(sender, MainMenuButton)
        b.BackColor = Color.White
        b.ForeColor = Color.Black
    End Sub

In my case on click event button color is changed but when I click on another button function SetButtonColor doesn't apply default colors back.
Below is my code which is basically copy-paste of your code:

Code: [Select]
    Private Sub MMPB_Zone1_Click(sender As Object, e As EventArgs) Handles MMPB_Zone1.Click, MMPB_Zone2.Click, MMPB_Zone3.Click, MMPB_MainPLC.Click, MMPB_UC_Logo.Click, MMPB_BonAppe.Click
        For i = 0 To Controls.Count - 1
            SetButtonColor(Controls(i))
        Next

        Dim b As MainMenuButton = DirectCast(sender, MainMenuButton)
        b.BackColor = SystemColors.ButtonHighlight
        b.ForeColor = SystemColors.WindowText
    End Sub

    '* Set all buttons to non-selected
    Private Sub SetButtonColor(ByVal container As Control)
        Dim index As Integer
        While index < container.Controls.Count
            ' If TypeOf container.Controls(index) Is Panel Then
            If container.Controls(index).HasChildren Then
                CheckContainerControlsForOpenOnStartup(container.Controls(index))
            Else
                If TypeOf container.Controls(index) Is MainMenuButton Then
                    container.Controls(index).BackColor = SystemColors.ButtonFace
                    container.Controls(index).ForeColor = SystemColors.WindowText

                End If
            End If

            index += 1
        End While
    End Sub


Any ideas what can be wrong or missing?

Thanks
« Last Edit: September 30, 2018, 04:18:38 PM by boldive »

boldive

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Forms layout with MainMenu Buttons
« Reply #5 on: October 05, 2018, 09:00:14 AM »
The problem with OpenOnStartup is fixed. I didn't use provided MainMenu form under section FormChangeControl => MainMenuDriven and used my own. This is why code responsible for flag OpenOnStartup was missing and I had to add it by myself. Original MainMenu file already has it.

To highlight MainMenuButton after click I used the code below
Code: [Select]
    Private Sub FormChangeButton_Click(sender As Object, e As EventArgs) Handles MainMenuButton1.Click, MainMenuButton2.Click, MainMenuButton3.Click
        SetButtonColor()
        Dim b As MainMenuButton = DirectCast(sender, MainMenuButton)
        b.BackColor = SystemColors.ButtonHighlight
        b.ForeColor = SystemColors.WindowText
    End Sub

    ' Set all buttons to non-selected
    Private Sub SetButtonColor()
        Dim index As Integer
        While index < Controls.Count
            If TypeOf Controls(index) Is MainMenuButton Then
                DirectCast(Controls(index), MainMenuButton).BackColor = SystemColors.ButtonFace
                DirectCast(Controls(index), MainMenuButton).ForeColor = SystemColors.ControlText
            End If
            index += 1
        End While
    End Sub

I still have problem to highlight buttons on submenu where FormChangeButton has to be used.

Sumbenu  FormChangeButtons sits on the forms called from MainMenu inside System.Windows.Forms.Panel where Panel name is "Navigation"
The code below doesn't work right. It highlights button on the second click, however form changes after single click.

Code: [Select]
    Private Sub SetSMButtonColor()
        Dim index As Integer

        While index < Navigation.Controls.Count
            If TypeOf Navigation.Controls(index) Is FormChangeButton Then
                DirectCast(Navigation.Controls(index), FormChangeButton).BackColor = SystemColors.ButtonFace
                DirectCast(Navigation.Controls(index), FormChangeButton).ForeColor = SystemColors.ControlText
            End If
            index += 1
        End While
    End Sub

    Private Sub FormChangeButton1_Click(sender As Object, e As EventArgs) Handles FormChangeButton1.Click, FormChangeButton2.Click, FormChangeButton3.Click, FormChangeButton4.Click, FormChangeButton5.Click
        SetSMButtonColor()
        Dim b As FormChangeButton = DirectCast(sender, FormChangeButton)
        b.BackColor = SystemColors.ButtonHighlight
        b.ForeColor = SystemColors.WindowText
    End Sub

So far I don't have a solution.

Insted of declaring  Private Sub SetSMButtonColor() on every form would be nice to have this function as global,
 Public Sub SetSMButtonColor() for example . In Solution Explorer I mage new item "Global Functions.vb" as Module to keep all global functions inside. The syntax of code above doesn't fit into syntax of global functions. Need help to figure out how to do it.

Thanks