Close WPF window that host Pages - c#

Im currently learning C# WPF. Now Im just trying to understand how navigation works.
I have created a test app that includes 2 buttons. One that navigates to the next page and another to open a new window.
Navigation between pages is not a problem.
I was able to navigate from page1 to page2 using a button. The code below is written in my Page1.xaml.cs
private void button_Click(object sender, RoutedEventArgs e)
{
Page2 p2 = new Page2();
this.NavigationService.Navigate(p2);
}
The problem is when I try to open a new window and close the previous one with a button, it doesnt work. (I also wrote this on my Page1.xaml.cs)
private void button_Copy_Click(object sender, RoutedEventArgs e)
{
Window1 win1 = new Window1();
win1.Show();
this.Close();
}
Its giving me an error code CS1061 and telling me that it does not contain a definition for 'close'.
Here is the complete code of my Page1.xaml.cs:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
Page2 p2 = new Page2();
this.NavigationService.Navigate(p2);
}
private void button_Copy_Click(object sender, RoutedEventArgs e)
{
Window1 win1 = new Window1();
win1.Show();
this.Close();
}
}
}

Use
this.parent
To access the Window the page is in
var goToWindow = new Window1();
goToWindow.Show();
Window windowToClose = (Window)(this.Parent);
windowToClose.Close();

It's a bit of a guess, as I haven't seen enough of your code. If the call this.Close() is placed outside the class defining the window that you're trying to close, there's no such method in the scope of this.

I figured out a work around. What you could do, is create a button at the bottom of the window that hosts the page and from that button, set the open new window and close property on click. (If you want to close the page and open a new window).
This is what I mean
<Grid>
<!--Your page frame -->
<Frame Name="buildcaseFrame" NavigationUIVisibility="Hidden" />
<!--This button will appear on all the pages-->
<!--You can choose where to place the button-->
<StackPanel VerticalAlignment="Bottom">
<Button x:Name="btnCloseButton" ToolTip="Go Back to Main Menu Without Saving" Cursor="Hand" Content="Cancel" Click="closeButton_Click"/>
</StackPanel>
</Grid>
This will allow you to close the page and open a new window. Like so...
private void BtnCloseButton_Click(object sender, RoutedEventArgs e)
{
Window1 win1 = new Window1();
win1.Show();
this.Close();
}

Related

What is the previous window called in WPF

I know the current window can be used with "this" but is there anything I can use to call the previous window?
For example I have this code going off when I press a button
Buyer_Login BuyerWindow = new Buyer_Login();
Visibility= Visibility.Hidden;
BuyerWindow.Show();
I need to be able to go back to the first window and I need to close the BuyerWindow and I was going to do it with this.Close();
What can I do to make the first window's visibility visible again?
You could handle the Window.Closed event:
MainWindow.xaml.cs
private void OnClick(object sender, EventArgs e)
{
var loginWindow = new BuyerLogin();
loginWindow.Closed += OnBuyerLoginWindowClosed;
this.Visibility = Visibility.Hidden;
loginWindow.Show();
}
private void OnBuyerLoginWindowClosed(object sender, EventArgs e)
=> this.Visibility = Visibility.Visible;
You should consider to show the login window from the App.xaml.cs before you show your main window (recommended):
App.xaml.cs
private async void App_OnStartup(object sender, StartupEventArgs e)
{
var loginWindow = new BuyerLogin();
bool? dialogResult = loginWindow.ShowDialog();
if (dialogResult.GetValueOrDefault())
{
var mainWindow = new MainWindow();
mainWindow.Show();
}
}
App.xaml
<Application Startup="App_OnStartup">
<Application.Resources>
</Application.Resources>
</Application>
There is a collection of open windows.
App.Current.Windows;
It depends on exactly what you're doing opening windows.
If you start up then mainwindow will be [0] in that collection.
Say you then open an instance of window1.
That in turn opens an instance of window2.
There is a bit of a complication if you f5 in visual studio because it opens adorner windows.
Setting that aside for a moment.
When I write code to do what I describe above.
In Window2 I handle content rendered:
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
var wins = App.Current.Windows;
wins[1].Close();
}
}
That instance of Window1 is closed.
Your new window is very likely the last window in that zero based collection and the previous one the window before that.
You could perhaps search the collection and find index for "this" and subtract one if you're doing more complicated things.
The chances are though, you want to close the window indexed by the count of that collection minus 2. Because it's zero based.
With my exploratory code, window1 closes with this:
private void Window_ContentRendered(object sender, EventArgs e)
{
var wins = App.Current.Windows;
wins[wins.Count - 2].Close();
}
Personally, I prefer single window apps and switch out the content in part of mainwindow. Leaving navigation buttons etc static in mainwindow.
If you're effectively opening one other window and closing the previous to do things then maybe you could consider a single window app instead.

WPF - Go back to first window from second window

I have a MainWindow page and a LoadingWindow. The MainWindow has a button that closes itself and opens LoadingWindow. What I want is when the user closes the Loading window to go back to the MainWindow as a new instance.
MainWindow.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
LoadingWindow load = new LoadingWindow(calibration , "MainWindow" , this);
Mouse.OverrideCursor = null;
Application.Current.MainWindow.Close();
load.ShowDialog(); // Exception is here the next time it is called
}
LoadingWindow.xaml.cs
private void Close_Button(object sender, RoutedEventArgs e)
{
MainWindow main = new MainWindow();
this.Close();
main.ShowDialog();
}
Now when I try to close the Loading window and press the Button_Click, the following error shows up at the load.ShowDialog() although I am declaring a new instance of it.
System.InvalidOperationException: Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed
I read that you cannot open a window after you closed it, but I am having a new instance which should not make this problem.
On your main window don't use the Application.Current.MainWindow instance, use this.Close() instead.
private void Button_Click(object sender, RoutedEventArgs e)
{
LoadingWindow load = new LoadingWindow(...);
Mouse.OverrideCursor = null;
//Application.Current.MainWindow.Close();
this.Close();
load.ShowDialog(); // Exception is here the next time it is called
}
Refer to this thread & this for clarification on the difference.

ShowDialog() ends prematurely if called from hidden windows

Consider this code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Title = DateTime.Now.ToString();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Hide();
new MainWindow().ShowDialog();
Show();
Debug.WriteLine(Title);
}
}
The XAML is trivial:
<Window x:Class="ShowHide.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Button
Content="Test"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="Button_Click"/>
</Grid>
</Window>
If I go "up", it works as expected - this window gets hidden, the new one is created and is shown as a modal window. But when I close the currently visible window, all hidden windows "underneath" get shown at once and they're not modal anymore. Multiple lines appear in the output window.
However, if I comment out the Hide() call, the problem doesn't seem to arise, i.e. I get to close modal windows one by one in reverse.
To reproduce:
Run the code.
Press the "Test" button. The current window will hide and the new one will appear.
Press the "Test" button in the new window. Another window will be created again. You can repeat this step as many times as you want.
Close the window. Older windows will re-appear all at once and neither will be modal.
Is this by design? What would your workaround be?
This is by design, as you hide your Modal window and display it again using Show() rather than ShowDialog(), so you could modify your code as below:
bool isChild;
private void Button_Click(object sender, RoutedEventArgs e)
{
Hide();
new MainWindow() { isChild = true }.ShowDialog();
if (isChild)
{
ShowDialog();
}
else
{
Show();
}
}
The code works just as you write. You call a method Show(), but you should write ShowDialog(). Just change this code:
Hide();
new MainWindow().ShowDialog();
Show();
To:
Hide();
new MainWindow().ShowDialog();
ShowDialog();

How to navigate between windows in WPF?

I have tried to set up a click event for a button that opens another window,but the error I'm getting at NavigationService is that the project doesn't contain a definition for it.
This is how I'm trying to call the page at present:
private void conditioningBtn_Click(object sender, RoutedEventArgs e)
{
this.NavigationService.Navigate(new Uri("TrainingFrm.xaml", UriKind.RelativeOrAbsolute));
}
Can someone point me in the right direction with this or show alternatives to this method for window navigation?
NavigationService is for browser navigation within WPF. What you are trying to do is change to a different window TrainingFrm.
To go to a different window, you should do this:
private void conditioningBtn_Click(object sender, RoutedEventArgs e)
{
var newForm = new TrainingFrm(); //create your new form.
newForm.Show(); //show the new form.
this.Close(); //only if you want to close the current form.
}
If, on the other hand, you want your WPF application to behave like a browser, then you would need to create Pages instead of Forms, and then use a Frame in your application to do the navigation. See this example.
If you want to navigate from Window to Window:
private void conditioningBtn_Click(object sender, RoutedEventArgs e)
{
Window1 window1 = new Window1();
// window1.Show(); // Win10 tablet in tablet mode, use this, when sub Window is closed, the main window will be covered by the Start menu.
window.ShowDialog();
}
If you want to navigate from Window to Page:
private void conditioningBtn_Click(object sender, RoutedEventArgs e)
{
NavigationWindow window = new NavigationWindow();
window.Source = new Uri("Page1.xaml", UriKind.Relative);
window.Show();
}
In order to use NavigationService you should use the Page and not the Window class

How do I open a second window from the first window in WPF?

I am new to WPF. I have two windows, such as window1 and window2. I have one button in window1. If I click that button, the window2 has to open. What should I do for that?
Here is the code I tried:
window2.show();
Write your code in window1.
private void Button_Click(object sender, RoutedEventArgs e)
{
window2 win2 = new window2();
win2.Show();
}
When you have created a new WPF application you should have a .xaml file and a .cs file. These represent your main window. Create an additional .xaml file and .cs file to represent your sub window.
MainWindow.xaml
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Open Window" Click="ButtonClicked" Height="25" HorizontalAlignment="Left" Margin="379,264,0,0" Name="button1" VerticalAlignment="Top" Width="100" />
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonClicked(object sender, RoutedEventArgs e)
{
SubWindow subWindow = new SubWindow();
subWindow.Show();
}
}
Then add whatever additional code you need to these classes:
SubWindow.xaml
SubWindow.xaml.cs
private void button1_Click(object sender, RoutedEventArgs e)
{
window2 win2 = new window2();
win2.Show();
}
Assuming the second window is defined as public partial class Window2 : Window, you can do it by:
Window2 win2 = new Window2();
win2.Show();
This helped me:
The Owner method basically ties the window to another window in case you want extra windows with the same ones.
LoadingScreen lc = new LoadingScreen();
lc.Owner = this;
lc.Show();
Consider this as well.
this.WindowState = WindowState.Normal;
this.Activate();
In WPF we have a couple of options by using the Show() and ShowDialog() methods.
Well, if you want to close the opened window when a new window gets open then you can use the Show() method:
Window1 win1 = new Window1();
win1.Show();
win1.Close();
ShowDialog() also opens a window, but in this case you can not close your previously opened window.
You will need to create an instance of a new window like so.
var window2 = new Window2();
Once you have the instance you can use the Show() or ShowDialog() method depending on what you want to do.
window2.Show();
or
var result = window2.ShowDialog();
ShowDialog() will return a Nullable<bool> if you need that.
You can create a button in window1 and double click on it. It will create a new click handler, where inside you can write something like this:
var window2 = new Window2();
window2.Show();
You can use this code:
private void OnClickNavigate(object sender, RoutedEventArgs e)
{
NavigatedWindow navigatesWindow = new NavigatedWindow();
navigatesWindow.ShowDialog();
}

Categories