Need To Close A Panel When Clicked Outside (Lost Focus) - vb.net

I have an issue that I cannot seem to overcome.
In my application, I have a custom class that loads a form into a panel upon startup. Then when I click a button on my main form I show the panel as visible revealing the form to the user.
My problem is that I want to be able to hide the panel when a user clicks outside of it (back onto the main form).
so far I have tried Form_Deactivate, Form_Leave, Form_LostFocus, Panel_Leave and Panel_LostFocus events but nothing will seem to trigger an event consistently to hide the panel. The only thing that works is if the user clicks inside the form (on a listview control) once the form is visible and then clicks outside of the form.
Is there anyway I can ensure this event gets called everytime whether the user clicks the form or not?
So far my code looks something like:
Public Class cls_UserObjects
Private frm As frmUsers
Public pnl As Panel
Public Sub ShowUserPanel()
Try
frm = New frmUsers
frm.TopLevel = False
pnl.Controls.Add(frm)
frm.Show()
frm.Focus()
....
End Class
Then in my main form I call the code below to build the form into the panel:
class_Users.pnl = pnlUsers
class_Users.ShowUserPanel()
And pnlUsers.Visible = True to show it to the user
I just can't seem to close it. I understand that Panels don't support the LostFocus properly, however, I can't find away around this. Maybe it has something to do with how I am opening my form/panel but I was advised to use classes to open forms so I can have more control over the controls within my forms from outside calls.
Any help appreciated. Thanks

MouseLeave event works, the panel hides immediately once it leaves the panel.
Private Sub Panel1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel1.MouseLeave
Panel1.Visible = False
End Sub

Related

How to dispose of a form within a panel upon closing the main form or upon another button click event?

Disclaimer: I only have beginner to slightly intermediate experience with VB.net
Hello, I was tinkering around with some design ideas for a project and I ran into a problem that I haven't found a solution to. I have a win form with some buttons and a panel. When the user presses a button, a border-less form is loaded into the panel. The problem is this: when the main form is closed, Visual Studio does not stop debugging, presumably because the forms in the panel are not disposed of.
Win Form image
The instance of the panel form is declared in the button click event. How can I destroy that instance from another sub? If I click another button, the first panel form doesn't go away. Is there a better way to accomplish this? I'm still learning, so I'm often not aware of all the different ways to solve a problem. Thanks everyone!
Public Class frm_Clients
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim search As New Search
search.TopLevel = False
search.Dock = DockStyle.Fill
Panel1.Controls.Add(search)
search.Show()
End Sub
Private Sub frm_Clients_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
' What should I write here?
End Sub
End Class
Here's a snippet of what to do to close the windows when another button is pressed.
For Each form In Panel1.Controls.OfType(Of Form).ToList()
form.Close()
Next
Then I would suggest that you set search.Owner to the Form holding the Panel. That means that when the Owner is closed, so are the children.
search.Owner = Me

Why does my new form move behind the opener?

I'm not going to post a bunch of code here since I do not think it is a code issue.
Here is a link to my original question where I have shown the code if you are interested. Code
Just as a test I created a blank form window (Form1.vb) and no code gets passed to it and no code runs when it opens. If I do Form1.Show() from a MenuStrip Control or a Button Control, the window opens and stays on top. Now if I do Form1.Show() from a TreeView Control, the window opens and goes behind the window with the TreeView Control.
So my question is, what is different about the TreeView opening a form vs a button or other control?
I am using the basic VB TreeView Controll, and the new form is being called in AfterSelect method for the TreeView.
The AfterSelect works if you use your keyboard navigation to select a node, but it doesn't work when you use the mouse because the mouse capture is forcing the parent form to remain in focus. You would have to run your code after the AfterSelect event:
Private Sub TreeView1_AfterSelect(sender As Object, e As TreeViewEventArgs) _
Handles TreeView1.AfterSelect
Me.BeginInvoke(New Action(Sub()
Dim f2 As New Form2
f2.Show(Me)
End Sub))
End Sub
Use the Form.Show(parentForm) option, this will always put the new form on top of the old one.
have you tried Form1.ShowDialog() ? or if you don't want to show it as a dialog you should use:
Form1.Show()
Form1.BringToFront()

Override button click event from another form

Is there a way to override a forms button click event from a parent form?
For example, here's kind of what I have going on...
Dim newForm As New FormB
newForm.someproperty1 = True
newForm.someprpoerty2 = False
newForm.Show(Me)
I need to know what button was clicked when newForm is closed. I would normally use 'ShowDialog', but I can't since newForm needs to open up a DIFFERENT form that can't open as a Dialog... long story short, without a complete rewrite of our entire software, i can't use the ShowDialog.
Anyways, is there anyway that I can add button click events from another form? Something like...
Dim newForm As New FormB
newForm.btn1.click = SomeNewFunctionOrSubroutine()
newForm.btn2.click = SomeOtherFunctionOrSub()
newForm.Show(Me)
I've been looking at events and eventhandlers, but they aren't making too much sense...
Any tips?
You could call AddHandler on your button in FormB (provided that its Modifier property is Public)
' This code is inside your Parent form
AddHandler newForm.btn1.click, AddressOf Me.SomeOtherFunctionOrSub
' This code is inside your Parent form
Protected Sub SomeOtherFunctionOrSub(sender as Object, e As EventArgs)
......
End Sub
Adding an Handler is a common practice to intercept the actions on a different form (For example, you probably will need also to intercept the Form.Closing event in case you want to have just one instance of newForm open at any time.)
An other approach (more complex) is subscribing to a custom event and requires the cooperation of FormB code. But in this scenario it doesn't seem to be necessary.

All Controls Click event on form

Is there a simple way to Activate the form when any controls in the form is clicked like datagirdview, panel, menustrip, button, textbox, label, etc....
it happens that my project can show many different form and it's hard for me to activate one form when it's on the back of the active form. I need to clicked the border of the form to activate it.
most likely your problem arises because your form is MDI child.. you'll have to click the menu bar to activate the form.. but if you have a borderless form, clicking on controls wont activate the form.. again, this usually happens on MDI but it shouldnt happen on a regular winform.. unless you have other running events in the background that interferes with the process.
You question is not clear at all, and I don't know what you are trying to archieve, but for executing something with a click event you have to add the handler for every control.
If you are declaring it not dinamically just:
Private Sub ControlsClick(sender As Object, e As EventArgs) _
Handles Panel1.Click, Button1.Click, TextBox2.Click ' etc.
Me.Activate 'Or Whatever
End Sub
You have to add the handler for each control. The same if you do it dinamically:
Private Sub InitializeClickHandlers(sender As Control, Optional bChilds As Boolean = True)
For Each elem As Control In sender.Controls
AddHandler elem.Click, AddressOf ControlsClick(elem, New EventArgs)
If bChilds AndAlso elem.Controls.Count > 0 Then
Call InitializeClickHandlers(sender)
End If
Next
End Sub
Then, for every control in the form, you call it like: Call InitializeClickHandlers(Me)
Or, for every control inside a panel: Call InitializeClickHandlers(Panel1)

vb.net How to get working scrollbars when moving nested form controls inside a parent panel

I have a container (a panel) which can contain multiple Form controls.
(Form.TopLevel = False)
When the user moves the Forms around I would like to display scrollbars when a form is out of the panel bounds.
When I register the Form.Move event, I can set the AutoScrollPosition. This works unless the user uses the scrollbars.
The problem is that the form.move event is also fired when the scrollbars are used. The result is that the scrollbars don't work. (And I have currently no idea how to find out whether the form has been moved by the mouse or by the scrollbar)
So the question is: How can I make the scrollbars of the panel appear/work when a form (or multiple) forms of the panel exceed the boundaries? I think there must be a simpler way than to handle the move event..
Note:
The panel is placed inside a Infragistics DockableControlPane. (Managed by an UltraDockManager)
(So there are multiple panels which contain at least one form per panel)
The reason is that the "panels" should appear as tabs, can be moved around using the DockManager and display their "sub" forms (Which also can be moved around on their panel).
Any idea would be great
It looks like the LocationChanged event could be used. Example with only one form:
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
Dim f As New Form
f.TopLevel = False
AddHandler f.LocationChanged, AddressOf Form_LocationChanged
Panel1.Controls.Add(f)
f.Show()
Call Form_LocationChanged(f, EventArgs.Empty)
End Sub
Private Sub Form_LocationChanged(sender As Object, e As EventArgs)
With DirectCast(sender, Form)
Panel1.AutoScrollMinSize = New Size(.Bounds.Right, .Bounds.Bottom)
End With
End Sub
Using an MDI form seems to be more appropriate though for something like this.