host WPF windows in another WPF window - wpf

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.

Related

make enter button of textbox

i have textbox multi way to fill it
i can fill it from keyboard normally and the other way by clicking button i created on forum something like calculator
when i click button 1 the textbox fill by number 1 and so
and i have button name and work should be like enter key
i have event keydown to send the value i fill it on the text box and work fine
but i need the button that called enter work as the event keydown of the textbox
in short word i need to use touchscreen to enter number to textbox and button to send the value of the textbox to my work
If you want to execute the same code at two different occasions you should put your code in a separate method and then call that at will.
By dividing your code like this you improve both readability and debuggability, and you make your code easier to understand and update.
Here's a brief example:
Private Sub TextBox1_KeyDown(sender As Object, e As System.Windows.Input.KeyEventArgs) Handles TextBox1.KeyDown
If e.Key = Key.Enter Then
UpdateStatus("Enter was pressed.") 'Call custom method.
End If
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
UpdateStatus("Button1 was pressed. Hello World!") 'Call custom method.
End Sub
Private Sub UpdateStatus(ByVal Text As String) 'Custom method declaration.
TextBox1.Text = Text
'In here is where you'd put your code.
End Sub

Visual Basic sender not coming back as control

I have a windows application with 2 forms.
frmMain has a button (btnEditAgent) on it that opens frmEditAgent:
Public Sub btnEditAgent_Click(sender As Object, e As EventArgs) Handles btnEditAgent.Click
frmAgentEdit.ShowDialog()
End Sub
Then on frmEditAgent load:
Private Sub frmAgentEdit_Load(ByVal sender As Object, e As EventArgs) Handles MyBase.Load
MsgBox(sender.Name, vbOKOnly, "verify")
End Sub
The sender comes back as "frmEditAgent" and not "btnEditAgent"
I do not understand why this is happening. In order for the rest of my code to work I need to know which button opened frmEditAgent. Why is sender referring to the same form?
The sender of the Load event is the Form that was just loaded. The semantics of sender wouldn't make sense otherwise.
Think of it this way: the button opens the form, but the form does its own loading, and so calls its own Load event with itself as the sender.
If you want to know which button opened the form, then you can add an instance variable to your dialog form's class and then just set that variable in btnEditAgent_Click.
frmAgentEdit can then just use that instance variable to know which button caused it to be opened.

close wpf user control in VB.NET

I'm stuck on this issue, please help.
I created an user control named "CreateNewCase_uc" within which I created a button Close named "btnClose"
In my MainWindow, I created a Grid named "grid1" and a button Open named "btnCreateNewCase" with this code
Private Sub btnCreateNewCase_Click(sender As Object, e As RoutedEventArgs)
Dim cnc As CreateNewCase_uc = New CreateNewCase_uc
grid1.Children.Clear()
grid1.Children.Add(cnc)
End Sub
My question : which Code I need to Write for my bntClose button which is inside the user control to close or make disappeared the user control in VB.NET
Thanks in advance for your help.
You need to get the Parent control then remove it.
' from inside your close button on UC.
Dim parent = TryCast(Me.Parent, Grid))
If Not parent Is Nothing Then
parent.Children.Remove(Me)
End If
You may simply set the UserControl's Visibility to Collapsed:
Private Sub btnCreateNewCase_Click(sender As Object, e As RoutedEventArgs)
Me.Visibility = System.Windows.Visibility.Collapsed
End Sub

Open User Control from user control in main window grid WPF

Maybe first I will tell about my application.
When for example an employee will log into my application, he will have loaded "Employee Menu":
Dim Empl As New Employee
MainGrid.Children.Add(Empl)
Grid.SetRow(Empl, 1)
This is from Window_Loaded event. Menu is User Control, and there I have few buttons to open and operate another user controls. When I press for example button "Question":
Public Class Employee
Dim mw As New MainWindow
Private Sub btnQuestionAdd_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnQuestionAdd.Click
Dim Que As New QuestionAdd
mw.MainGrid.Children.Add(Que)
Grid.SetRow(Que, 2)
Grid.SetColumn(Que, 1)
End Sub
End Class
I don't know why nothing is loading after button_click.....
Is it so hard to navigate main windows grid from other controls?
This is just a guess as you've not provided much information, but I noticed the following issue which may be the culprit.
In your first code snippet, you seem to be creating the employee from the MainForm:
Dim Empl As New Employee
MainGrid.Children.Add(Empl)
Grid.SetRow(Empl, 1)
Your following comment would seem to confirm that assumption:
This is from Window_Loaded event. Menu is User Control, and there I have few buttons to open and operate another user controls. When I press for example button "Question"
And yet, in your Employee class, you are creating a brand new instance of MainWindow and then adding data to it:
Public Class Employee
Dim mw As New MainWindow
Private Sub btnQuestionAdd_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnQuestionAdd.Click
Dim Que As New QuestionAdd
mw.MainGrid.Children.Add(Que)
Grid.SetRow(Que, 2)
Grid.SetColumn(Que, 1)
End Sub
End Class
If this observation is correct, then I think you need to go back to the books and understand the concept of classes and instances.
You essentially created a second form (which is hidden because you never explicitly show it) and then modify this second form rather than the original. To prove this hypothesis, try adding the following line of code:
Public Class Employee
Dim mw As New MainWindow
Private Sub btnQuestionAdd_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnQuestionAdd.Click
Dim Que As New QuestionAdd
mw.MainGrid.Children.Add(Que)
Grid.SetRow(Que, 2)
Grid.SetColumn(Que, 1)
mw.Show() ' <---
End Sub
End Class
You'll likely see a second form pop up with all of the changes your were expecting on your first form.
As to how to fix this, the easiest path is going to be adding a parameter to your initializer ("Sub New") which accepts the MainForm as a value. You can then assign the value to a field or property (probably just your mw field) and continue on your merry way. This is going to give you headaches down the road, though, so it might be a good time to start learning more about software architecture, especially the concept of separation of concerns.

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!

Resources