How to run code on Exit vb.net - vb.net

I would just like to know how to run code in vb.net when the program is closed with the red cross in the top right of the screen.

Use Form.FormClosing Event - Read the Remarks on this event documentation for better implementation of your functionality.
It occurs before the form is closed.
Check FormClosingEventArgs properties for further manipulations:
e.CloseReason
e.Close
However, canceling the event will set to true the Cancel property of
the FormClosingEventArgs class that is passed as a parameter to the
parent form. To force all MDI parent and child forms to close, set the
Cancel property to false in the MDI parent form.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
sr.WriteLine("8 - FormClosing");
}
Windows Forms Events Lifecycle

You need to handle the FormClosing event: use the CloseReason property of the FormClosingEventArgs to determine why the form is closing - you want to look for CloseReason.UserClosing - and set the Cancel property to true if you want to cancel the form close.

Related

Winforms MouseEventArgs - How can I get a click modifier like control-click or alt-click?

I'm trying to figure out if it's possible to detect if a combobox was clicked by control click. Using Winforms.
If I just try capturing MouseEventArgs I don't see any modifiers.
Any ideas?
This seems to work in any event method.
if (Control.ModifierKeys = Keys.Control) Then
Debug.WriteLine("Ctrl+Click")
end if

VB.Net: Dynamicly created MonthCalendar does not fire LostFocus or GotFocus

I've created a form that has a tabbed control that gets users controls added to each tab dynamically and a StatusStrip at the bottom of the form. When the app starts, the user controls are loaded in the tabs based on security with at least 1 tab being loaded. On the StatusStrip, two ToolStripComboBoxes, 2 ToolStripButtons, 1 ToolStripLabel, and 1 ToolStripStatusLabel. Everything loads fine and works.
I've been taksed to have a MonthCalendar popup when the user presses one of the two buttons. Here's the code I use to do this:
If IsNothing(theCal) Then
theCal = New MonthCalendar
AddHandler theCal.DateSelected, AddressOf theCalDateSelected
AddHandler theCal.LostFocus, AddressOf theCalLostFocus
AddHandler theCal.GotFocus, AddressOf theCalLostFocus
theCal.Parent = Me
theCal.Top = StatusStripMain.Top - theCal.Height
theCal.Left = ComboBoxAvailableLegDay.Bounds.X
theCal.Anchor = AnchorStyles.Bottom + AnchorStyles.Left
theCal.Show()
theCal.BringToFront()
theCal.Focus()
Else
Me.Controls.Remove(theCal)
theCal = Nothing
End If
theCal is defined as Protected at the top of the form's class. So, pressing the button will create the MonthCalendar and position it correctly if it doesn't exists and if it does exists, then it is removed. This works with no problems.
My problem is that theCal never fires GotFocus or LostFocus. I've got the procedure theCalLostFocus defined as follows and it never thows the exception. I can put a breakpoint at the throw and the code never makes it to that point.
Private Sub theCalLostFocus(ByVal sender As Object, ByVal e As EventArgs)
Throw New NotImplementedException
End Sub
Clicking a date on theCal will call theCalDateSelected procedure, but clicking any other area of the form does not fire theCalLostFocus. Since the user may want to not select a date and I don't want to force them to have to press the button to remove theCal, I'd like to be able to remove theCal when it loses focus. Anyone have any idea why this is happening and anyone got a solution?
Thanks.
-NCGrimbo
i'm not that surprised that the focus event won't fire, because you add the handler before inserting it in the visual tree. try adding the handler after the call to show(). or maybe in the loaded event handler. Note that since you request the focus, your focus event handler will be called every time.
Rq : as it is written, your code has memory leak since you do not remove the event handler when you clear theCal, so since a reference is kept to theCal, neither theCal nor the event handler get cleared and this lead to memory leak (cyclical reference).

Binding Custom object to Checkbox in VB.NET

I am trying to bind a checkbox to a custom object boolean property as follows:
chkTableIsReadonly.DataBindings.Add(New Binding("Checked", objectBindingSource, "ApplyforVisa", True, DataSourceUpdateMode.OnPropertyChanged, False))
The custom class supports the INotifyPropertyChanged interface.
Everything works find when I initially bind the checkbox to a new object:
objectBindingSource.Datasource = new objectToBindTo
Here is the odd part:
If I check the box, the property Set gets called and the INotifyPropertyChanged event gets called and everyone is happy.
If I uncheck the same box, the property Set doesn't get called, the INotifyPropertyChanged event never gets called and (the worse part), I cannot navigate to another record.
I have tried capturing the CheckedChanged event to set the object.ApplyForVisa property manually, but no success. The property Set gets called and the INotifyPropertyChanged event gets called, but I am still locked on control and can't navigate.
I have tried calling bindingsource.endedit in the CheckedChanged event, no success.
It only matters if I uncheck the box. The checkbox is two-state - true or false.
All of my other bindings work just fine - text boxes, combo boxes, datagrid. Just not checkbox.
My only thought is that is seems to act like a binding source data error, but no error is thrown. If I add the data error event handler for the binding source, it never gets called.
Assuming the ApplyForVisa property is a Boolean, you can just fix this by setting formattingEnabled parameter for the Binding to False.
chkTableIsReadonly.DataBindings.Add( _
New Binding("Checked", objectBindingSource, "ApplyforVisa", _
False, DataSourceUpdateMode.OnPropertyChanged, False))

Why isn't the LostFocus event occurring?

With a listbox visible, I have clicked on the windows form hoping to use the listbox.lostfocus event to let me hide the listbox - but the event does not occur. I suppose I can use the form.click event to hide the listbox, but how would I get the form to accept focus?
A Form does not want to receive the focus. It was designed to be a container control, it makes sure that one of its child controls always gets the focus. It is technically possible to whack it over the head and make it lose that behavior:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.SetStyle(ControlStyles.ContainerControl, false);
}
protected override void OnClick(EventArgs e) {
this.Focus();
base.OnClick(e);
}
}
This is however a bad idea. A Form doesn't have any way to indicate that it has the focus, you'll also have to override OnPaint() to do something like draw a focus rectangle. If you don't then the user completely loses track of where the focus is located. Then there's the considerable inconvenience that nothing interesting can happen when the user uses the keyboard, a form doesn't have a use for it.
Don't do this. If you want to make a control disappear then add a menu item, toolbar button or a normal button to your UI. Something the user can click on.
the LostFocus event work when the focus move to another control like textbox,... or when the form all of it lost the focus you can use click event for the form to detect taht

Windows Forms: Unable to Click to Focus a MaskedTextBox in a Non TopLevel Form

Like the title says, I've got a Child form being shown with it's TopLevel property set to False and I am unable to click a MaskedTextBox control that it contains (in order to bring focus to it). I can bring focus to it by using TAB on the keyboard though.
The child form contains other regular TextBox controls and these I can click to focus with no problems, although they also exhibit some odd behavior: for example if I've got a value in the Textbox and I try to drag-click from the end of the string to the beginning, nothing happens. In fact I can't use my mouse to move the cursor inside the TextBox's text at all (although they keyboard arrow keys work).
I'm not too worried about the odd TextBox behavior, but why can't I activate my MaskedTextBox by clicking on it?
Below is the code that shows the form:
Dim newReportForm As New Form
Dim formName As String
Dim FullTypeName As String
Dim FormInstanceType As Type
formName = TreeView1.SelectedNode.Name
FullTypeName = Application.ProductName & "." & formName
FormInstanceType = Type.GetType(FullTypeName, True, True)
newReportForm = CType(Activator.CreateInstance(FormInstanceType), Form)
Try
newReportForm.Top = CType(SplitContainer1.Panel2.Controls(0), Form).Top + 25
newReportForm.Left = CType(SplitContainer1.Panel2.Controls(0), Form).Left + 25
Catch
End Try
newReportForm.TopLevel = False
newReportForm.Parent = SplitContainer1.Panel2
newReportForm.BringToFront()
newReportForm.Show()
I tried your code and got a good repro this time. As I mentioned in my original post, this is indeed a window activation problem. You can see this in Spy++, note the WM_MOUSEACTIVATE messages.
This happens because you display the form with a caption bar. That convinces the Windows window manager that the window can be activated. That doesn't actually work, it is no longer a top-level window. Visible from the caption bar, it never gets drawn with the "window activated" colors.
You will have to remove the caption bar from the form. That's best done by adding this line to your code:
newReportForm.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Which will turn the form into a control that's otherwise indistinguishable from a UserControl. You can still make it distinctive by using this code instead:
newReportForm.ControlBox = False
newReportForm.Text = ""
Either fix solves the mouse click problem.
This is a miserable bug and it took me a long time to find this question. We're doing exactly the same thing as the OP, displaying a Form inside a split container. My workaround was to add an event handler to the MaskedTextBox's Click event:
private void MaskedTextBoxSetFocus(object sender, EventArgs e)
{
var mtb = (MaskedTextBox)sender;
mtb.Focus();
}
This works for the MaskedTextBox but I'm concerned about other odd behavior due to this bug so I will probably set the border style as in the accepted answer.
The text box behavior is a symptom of the same problem. Something is swallowing mouse down notifications. It isn't explained by your code snippet. Forms indeed swallow the mouse click that activates them, but that is a one-time behavior and is turned off by setting its TopLevel property to False.
Not much left. One candidate is the Control.Capture property, turned on at the MouseDown event for a button so that the button can see the MouseUp event, no matter where the mouse moved. That's a one-time effect as well. Watch out for controls that set the Focus in a MouseDown event.
The other is some kind of IMessageFilter code in your form(s) that's eating WM_LBUTTONDOWN messages.