Prevent a form from closing when its parent closes - winforms

I am having a small issue with an application I am trying to develop.
I have notifications that popup using some code I found online (ToastForms). It pops up a little notification window in the bottom right hand side of the screen and then disappears. Works a treat.
However, my issue is that when I click on the notification window, I want to open another window modally from Form1. So for example, I have my main form (Form1), then a notification shows a second form (Form2) and when I click on Form2 it opens a third form (Form3).
This works fine, until Form2 auto closes. It then closes Form3 automatically.
Is there a way I can open a form from Form2 using Form1 as the parent? So closing Form2 has no affect on Form3?
I can't hide Form2 because if more notifications come through, it will stack these on top of the hidden forms. If Form3 is open for a long time, it could mean a lot of hidden notification forms.
Update
Ok, so my code to open a new notification looks like this:
If Notifications.Exists(Function(p) p.Id = tempDT.Rows(x)("id").ToString) = False Then
Notifications.Add(New Notification() With {.Id = tempDT.Rows(x)("id").ToString, .Description = "Call ID #" & tempDT.Rows(x)("id").ToString & " has now become overdue", .Read = False, .Type = "Overdue"})
Dim slice As New ToastForm(10000, "Call ID #" & tempDT.Rows(x)("id").ToString & " has now become overdue")
slice.Height = 100
slice.Show()
End If
Then, under the ToastForm I have a click event on the label control, so when the user clicks on the window (with a fullsize docked label control), it opens my notifications form against the main form (frmNewDashboard):
Private Sub messageLabel_Click(sender As Object, e As EventArgs) Handles messageLabel.Click
Dim frm As New frmShowNotifications
Me.Cursor = Cursors.WaitCursor
frm.Location = New Point(frmNewDashboard.Location.X + 1570, frmNewDashboard.Location.Y + 90)
frm.ShowDialog()
Me.Cursor = Cursors.Default
End Sub
Lastly, the ToastForm has a timer event. When the timer reaches its length, it calls the close event which closes both the ToastForm and the frmNotifications form:
Private Sub lifeTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles lifeTimer.Tick
'The form's lifetime has expired.
Me.Close()
End Sub

Related

Winform dialog show modal form wait for Dialogresult

I need to use "Show()" method for dialog winform using Ironpython
and i need to get result of button pressing and use it in another part of program
how can i wait for pressing OK in modal "Show()" dialog?
mform = Form3()
mform.Show()
# How to wait for button OK
Thx
Use ShowDialog() instead of Show().
Then check "if (mform.DialogResult == DialogResult.OK)"
Suppose you have a main form called Form1 and a secondary form called AddForm which presents some result when the [OK] button is pressed.
The main form then can subscribe to the FormClosed event of the secondary form and pull the result if the user clicked on the [OK] button.
This can all happen in the subroutine where the secondary form is shown
Private Sub Button1.Click(sender as Object, e as EventArgs) Handles Button1.Click
Dim dlg as New AddForm
AddHandler dlg.FormClosed, _
Sub(e,ev) TextBox1.Text = If(dlg.DialogResult = DialogResult.OK, dlg.Result, String.Empty)
dlg.Show()
End Sub
And in the secondary form make sure there is a property called Result which contains the results
The [OK] button has a handler like so
Private Sub Button1_Click(sender as Object, e as EventArgs) Handles Button1.Click
Result = ...
DialogResult = DialogResult.OK
Me.Close()
End Sub
and the [Cancel] button has a handler as so
Private Sub Button2_Click(sender as Object, e as EventArgs) Handles Button2.Click
DialogResult = DialogResult.Cancel
Me.Close()
End Sub

host WPF windows in another WPF window

here is my problem: i have created a main window called mainWindow in XAML (vb.net) and inside i have 2 buttons (valid and stop) and a grid in the center.
I have two others little windows (valid window and stop window) written in XAML (vb.net) which have buttons, textbox...
I want, when i click on valid button or stop button, display the valid window or the stop window inside the grid of my mainWindow, so i have this code in my mainWindow.vb:
enter code here
Private Sub valid_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles valid.Click
Dim content As Object = valid_.Content /*Classe valid_ (a window in xaml)*/
valid_.Content = Nothing
Me.Grid.Children.Add(content)
End Sub
Private Sub stop_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles stop.Click
Dim content As Object = stop_.Content
stop_.Content = Nothing
Me.Grid.Children.Add(content)
End Sub
So when i click on button valid in my mainWindow, it's ok it displays the valid window in my grid.
First problem: then when i click on button stop in my mainWindow, the stop window is placed just above the valid window, it is not nice, is there a way to clear the grid before display this second window?
And finally, the biggest problem: i need to click many times on valid button or stop button but when i click the second time i have a null reference exception: Me.Grid.Children.Add(content) content is null after the first call so i am only able to click one time on my button.
How can i fix it in order to click many times on my buttons please?
I give you thanks.
Yet again, someone writes some invalid code and then says why isn't this code working? If you look at your code, you should see something:
Private Sub valid_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles valid.Click
Dim content As Object = valid_.Content /*Classe valid_ (a window in xaml)*/
Me.Grid.Children.Add(content)
End Sub
I'm guessing that you have a private variable for your Valid Window as you call it: valid. On this line, what are you doing to your variable?:
valid_.Content = Nothing
That's right! You're setting its Content property to null. Therefore, I'm not really sure why you were surprised that it was null after the first attempt.
How can i fix it in order to click many times on my buttons please?
Try removing the line that sets the Content property to null.
UPDATE >>>
Your problem is really caused by the fact that you cannot display any UI element in two places at once. Your whole idea of copying the Window.Content to your DataGrid is entirely wrong, but in the name of brevity, your fix is simply to move your content back to the Window, rather than setting it to null each time. Try something like this:
Private Sub valid_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles valid.Click
If Me.Grid.Children.Count > 0 Then 'Put content back where it belongs
Dim oldContent = Me.Grid.Children(0)
stop.Content = oldContent
Me.Grid.Children.Remove(oldContent)
EndIf
Dim content As Object = valid_.Content /*Classe valid_ (a window in xaml)*/
valid_.Content = Nothing
Me.Grid.Children.Add(content)
End Sub
Please forgive any code mistakes, as I don't write VB.NET. Also, you'll need to update your other method likewise.

How to Close a Window Containing a Frame, NavigationService and Timer

In my project I've got a MainWindow that opens up a second Window. Inside the second Window there is a Frame and I start a navigationservice inside the Frame. Also in the second Window I've got a KeyDown method that calls Me.Close when the user presses the Escape key. Anyway, when the second Window closes a System.Windows.Threading.DispatcherTimer() inside one of the pages in the navigation service doesn't end. Any ideas on how can I close the second Window and terminate the DispatcherTimer inside the navigationservice?
Thanks
Mike
p.s. I can supply source code if anyone wants to look at what I've got...
(Hey EkoostikMartin - this is a follow up to your comments..)
So I've made some progress on this. I've add:
AddHandler Me.KeyDown, AddressOf Page_KeyDown
AddHandler Me.PreviewKeyDown, AddressOf Page_PreviewKeyDown
to the Page that has the timer. And inside the page I've defined both methods like:
Private Sub Page_KeyDown(sender As Object, e As KeyEventArgs)
If e.Key = Key.Escape Then
dTimer.Stop()
MessageBox.Show("Exit Page")
End If
End Sub
Private Sub Page_PreviewKeyDown(sender As Object, e As KeyEventArgs)
If e.Key = Key.Escape Then
dTimer.Stop()
MessageBox.Show("Exit Page")
End If
End Sub
And the second Window has this:
Private Sub Window_KeyDown(sender As System.Object, e As System.Windows.Input.KeyEventArgs)
'Escape Key Exits Program
If e.Key = Key.Escape Then
Me.Close()
End If
End Sub
So when I'm in the navigation service and navigated to the page with the Timer and I press "Esc" I get the message "Exit Page" and then the Window closes. This is good!
(I don't think I need both the KeyDown and PreviewKeyDown. When I press "Esc" I'm actually getting two "Exit Page" pop-ups)
There is a problem though: It seems like the Page doesn't get the KeyDown events unless I move the focus to a textbox or combobox and if I don't do this pressing the "Esc" key calls the second Window's Window_KeyDown and not the Page's KeyDown event which means the timer on the page doesn't get stopped even after the second Window is closed. Does anyone know a way to get the page focus when the page loads so that I can get the KeyDown event without manually changing the focus to a control on the Page?
Thanks!
Ok - I finally resolved this situation by way of a work around. In my second Window I've created a list of type DispatcherTimer:
Public clndTimer As New List(Of System.Windows.Threading.DispatcherTimer)
I can access this list from a Page that is inside my Navigation service. Here's the code in the Page:
Dim dTimer As New DispatcherTimer()
dTimer.Start()
Dim wSecondWindow As New SecondWindow
wSecondWindow = Window.GetWindow(Me)
If wSecondWindow IsNot Nothing Then
wSecondWindow.clndTimer.Add(dTimer)
End If
And then I capture the key event in the second Window. This is the method in the second Window:
Private Sub Window_KeyDown(sender As System.Object, e As System.Windows.Input.KeyEventArgs)
'Escape Key Exits Program
If e.Key = Key.Escape Then
For Each dt In clndTimer
dt.Stop()
Next
Me.Close()
End If
End Sub
Doing it this way I don't need either the Page_KeyDown or PreviewKeyDown methods in my Page which is good because they were behaving unreliably. (see answer above)
So what do you think? I'm not totally sure about the way I get the Second window or how I check it for null in the Page but otherwise this seems to make sense.
Thanks!

How can I navigate to a page from a dialog window?

I have a dialog window that I open from a record in a datagrid, this datagrid happens to be inside a Page that is navigated to inside a frame.
I have a button in this window, that when clicked, I would like to navigate the main window (which happens to be in a frame), to a different page that the datagrid is on.
How can I do this?
Here's the click code for the button:
Private Sub btnPlaceOrder_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnPlaceOrder.Click
Dim _M As New Main
_M.InnerFrame.Navigate(New ManualOrder())
Me.Close()
End Sub
figured it out for myself.
I needed to find the frame from the main application window in order to do this:
_F = Application.Current.Windows.Item(0).FindName("InnerFrame")

Only one windows should be open at once in WPF?

I am developing a WPF project in vb.net and have multiple windows in it. When user selects a menu item a new windows opens and the problem is when the user clicks on other menu item the current window should close by itself.
How do i achieve it?
Thanks!
I think you mean this based upon your comment:
Class MainWindow
Public Win3 As Window3 = New Window3()
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Win3.Show()
Me.Close()
End Sub
End Class
There are two ways to do this:
If the menu items share the same form then in the form create a subroutine, that you call instead of new, that checks if it is already shown/created and if not opens (as you already have). If it is open reload with the new information.
Otherwise before opening the new form go though the open forms (shown below from this website in C#):
FormCollection fc = Application.OpenForms;
foreach (Form frm in fc) {
//iterate through
}
For each form check if it's name is equal to one of the menu items and if it is close it (after saving if required). Then after you exit the for loop you open the new menu item.

Resources