Sharing Controls from multiple forms/classes - vb.net

I'm currently stuck in how to share controls between two forms.
This is what i want to do:
- I have several forms that have their own function.
- Now i want to bring them all to gather on one mainform.
Normally i do this by creating the following code:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim f As New Form2
GroupBox1.Controls.Add(f.Get_Groupbox_controls)
End Sub
End Class
This add all the control containing in Form2.Groupbox1 and adds it to Form1.Groupbox1.
Normally this works just fine for me.
Where "Get_Groupbox_controls" is a function that returns Form2.Groupbox1
Or if this doesn't works i display the entire form2 over form1 with a transparancykey. (this isn't a need solution, you have to do a lot of location calculating, but it works)
However now i got a form that has a lot going on. For the mainform i only want to display one Container(groupbox) but when the user clicks "More setting.." then it has to show the entire form with all the control on it.
The problem is when i use the container.controls.add() function i get an exception "Invoke or BeginInvoke cannot be called on a control until the window handle has been created "
The Error is logical because the entire form isn't made yet. But in order for the form to work properly it has to update the "hidden" UI controls (labels/buttons/etc)
So the main question is, how can i "port" a selection of controls from Form1 to form2 and keep all the handlers etc.. on Form1

If you have two forms where you want to place identical looking/functioning GroupBox sections, you may want to consider creating a custom user control that contains the shared functionality and can be placed in each form. User controls can even be added to a form through the form designer in Visual Studio.

Related

Is it possible to have one file that controls the look and feel of my custom title bar that I can access from any form?

I have an application with 60+ forms and instead of having 60+ copies of the same code in each form, I would like to have one instance of the code that is executed as any form is loading.
The subs are standard:
Protected Overrides Sub OnFormClosing(ByVal e As FormClosingEventArgs)
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
Protected Overrides Sub WndProc(ByRef m As Message)
I've made countless attempts using classes and modules, but am only able to get the forms that are hardcoded to work as desired.
I have triggered the OnPaint event residing in TitleBar (a non-form class), but I am unable to get TitleBar to apply any customizations to any form. Is there anyway I can circumvent the values in TitleBar's Me and MyBase, and assign them the calling form's values? Or can I get TitleBar to loan out its resources? Any help would be greatly appreciated. BTW, is there a word or phrase for what I'm trying to accomplish?
This has been a long round of trial and error.
Thank you
Create a form as normal and add that common code. In all your other forms, instead of inheriting the standard Form class, inherit the class you just created that contains the common code. That's how inheritance in OOP works.
If you're inheriting a form from a referenced library, you can select Inherited Form in the Add New Item dialogue but that doesn't work to inherit forms in the same project. At least, it doesn't work in an application project, although I haven't tested in a library project. The alternative is to add the form as normal, click the Show All Files button on the toolbar in the Solution Explorer, expand the node for your form, double-click the designer code file to open it and then manually edit the type that your form inherits from, e.g. change this:
Partial Class Form2
Inherits System.Windows.Forms.Form
to this:
Partial Class Form2
Inherits Form1

How do I take a combobox and a textbox in one form to transfer to another form combined?

I am creating a template generator and have added a sub form to add new templates vs what is already coded in. I am able to input the new template name in one Textbox and the data in a second textbox. When I hit the add button it sends the template name to the combobox on the first form like it is supposed to but it sends the data to the textbox in the first form not attached to the Template name. How do I link the two boxes when they send over?
I have done research in various websites and consulted with several books on trying to figure this out and the code I have is the closest I have gotten to figuring it out. I feel like I am only missing one link command but not sure what it is. I am reteaching myself how to use visual basic.
Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form1.ComboBox1.Items.Add(TextBox1.Text)
Form1.TextBox1.AppendText(TextBox2.Text)
Close()
End Sub
What I am expecting to happen is when I click the button it sends the newly created template over to the combobox on form1 to add to dropdown list of Templates and be usable. What is happening is Textbox1 is going to the combobox perfectly but textbox2 is not attaching to it.

Open 2 MDI Parent after opening the main menu form

I have 3 forms
MDI parent for TCP client
MDI parent for serial
The main menu form
I want to set the main menu form as the startupform then I want the 2 MDI parent to be loaded on the background. I don't want to show them, but I want to load them so I can trigger the on_load event of those 2 mdi parent which is to create serial/client child and connect automatically.
I've tried, but it didn't work.
Private Sub frmMenu_Load(sender As Object, e As EventArgs) Handles MyBase.Load
frmTcpMDI.show
frmSerialMDI.show
End Sub
I even tried adding a timer then starting it upon the show event of my startup form, the tick event is to open my frmTcpMDI and frmSerialMDI, still, it is not working.
Okay basically, if I understand what you want, you need a way to load your forms but not display them.
You want to run some code when the Load event occurs. However, as stated here by Microsoft :
Occurs before the control becomes visible for the first time.
Which basically screws you up...
So there is a few workaround for that.
Option 1 : You decide to run your code in the Sub New()
If you put all the code you want to run in the Sub New() of your child forms, you don't need to call Form.Show(), you just need to create the forms, and your code is running. When you actually need to display the form you call the Show() method and it's done.
Option 2 : You can't run your code in the Sub New()
If, for some reason, you can't run your piece of code in the Sub New() method, you still can do it with the load event. Just hide the form after showing it... Looks silly but will work.
First notice, still from Microsoft :
The Load event occurs when the handle for the UserControl is created. In some circumstances, this can cause the Load event to occur more than one time. For example, the Load event occurs when the UserControl is loaded, and again if the handle is recreated.
Which mean you have to be carefull to run your code only once...
Then, from your parent :
Dim myNewForm = new frmTCPMdi()
myNewForm.Show()'will call the Load event
myNewForm.Hide()'will hide the form, so it is loaded but invisible...
Honnestly, I think Option 1 looks better, but sometimes and for some reason you can't always go the easy way...

VB using me.close before opening new form

Hi Guys i'm new to Visual Basic Coding, and i can't seem to get where's my mistake on my coding, i'm trying to create a button that opens a new form while closing the current form.
i have two forms, form 1 is MainForm, form 2 is SearchForm
Whenever i use this code:
Private Sub SearchMButton_Click(sender As Object, e As EventArgs) Handles SearchMButton.Click
MainForm.Close()
SearchForm.Show()
End Sub
End Class
it will generate an error and says i need to replace MainForm.Close() into Me.Close()
When i Use this
Private Sub SearchMButton_Click(sender As Object, e As EventArgs) Handles SearchMButton.Click
Me.Close()
SearchForm.Show()
End Sub
End Class
It closes both Forms and it doesn't leave any Form Open. Kindly direct me to the proper path, thanks in advance.
You need to Hide the form rather than closing it. Since it's your main form, when it closes, the application exits.
Standard UI guidelines are to leave the main form open, and open search form on top of that. If you need to block the main form, while search criteria are selected, use .ShowDialog, instead of just .Show.
.NET WinForms programming pattern kind of implies that you never close your main form. If you deviate from this approach, you are guaranteed to encounter all sorts of layout and display issues. So please don't. You can .Hide the main form, if it needs to go to system tray or run in background.

VB.NET: How can you activate the childform when only the control inside is clicked?

*edit: OK, so this is my real problem, below scenario happens only when the form is MDIChild.. thanks for anyone that could provide me with the code
I have a form with labels, panels, buttons etc. Where I'm having problem is, while form2 is my active window/form and I clicked on a control inside form1, the form1 does not activate itself. What I would like to happen is for form1 to activate even when it's not the form I clicked, only the control inside it (any control)..
I'm thinking that if I clicked a control on the form, there's an event fired on the form. If I could only know of that certain event, that would help - maybe (coz I could just add Me.activate on that event if it exists). I've tried searching for series of events when a control (ex. label) is clicked but to no avail. I hope that someone could help me with this one.
Thanks in advance.
*edit
i will just try to make my question more understandable..
How can I activate the form when only the control is clicked (say, label or textbox)? My forms does not activate or focused when I click inside it except the form itself..
I can do this on one control..
Private Sub Label1_Click - Handles Label1.Click
Me.Activate()
End Sub
But what if I have 20 controls (labels, buttons, textbox, combobox, etc)? See? =)
EDIT: this answer does not apply to MDI applications.
I think what you really want to know is which one of your forms is currently the foreground window (if any). The first thing you need to understand is that a form instance lives inside a window, but the window's behavior is controlled somewhere higher up. Similar to how a form instance is identified by a variable pointing to the instance, a window can be identified by what's known as a window handle.
Knowing this, the proper way to find out whether a form is the "active" form is to:
find out the window handles of the windows containing our instances of Form1 and Form2
find out the window handle of the foreground window (which can be any window)
compare the value found in step 2 to all of the values found in step 1
Perhaps you'd then like to fire an event if the foreground window changes, but I'll leave the actual implementation up to you. There are probably several ways to perform step 1 and 2, but I can't give any solutions off the top of my head. Hopefuly I've put you back on the right track.
EDIT
Alternatively, you can use the form's Containsfocus property. If its value is True, you can safely assume that your form is the foreground window. I didn't find out about this property until after I wrote my own implementation, which I'll show you anyway:
One module containing only a windows API call
Friend Module NativeMethods
Friend Declare Function GetForegroundWindow Lib "user32.dll" () As IntPtr
End Module
Calling this method will return the window handle of the foreground window (if any).
One module containing the extension method for the Form class
Imports System.Runtime.CompilerServices
Public Module FormExtensions
<Extension>
Public Function IsForeground(f As Form) As Boolean
Return (f.Handle = NativeMethods.GetForegroundWindow)
End Function
End Module
Calling this method returns whether the specified form f has the same window handle as the foreground window.
Usage example
You could use a Timer that periodically checks whether a form is the foreground window.
Public Class Form1
Private WithEvents timer As New Timer With {.Enabled = True}
Private Sub timer_Tick(sender As Object, e As EventArgs) Handles timer.Tick
If Me.IsForeground() Then
Console.WriteLine("this instance of Form1 is the foreground window")
End If
End Sub
End Class
Like I said before, you can use Me.ContainsFocus instead of my extension method and it will work just fine.
In non-MDI forms, the form is automatically activated when you click any control inside it.