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();
Related
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.
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();
}
I've looked at all the suggested answers and nothing seems to fit what I'm looking for. I want to call a second form from my main form, hide my main form while the second form is active, and then unhide the main form when the second form closes. Basically I want to "toggle" between the two forms.
So far I have:
In my main form:
private void countClick(object sender, EventArgs e)
{
this.Hide();
subForm myNewForm = new subForm();
myNewForm.ShowDialog();
}
and in my second form I have:
private void totalClick(object sender, EventArgs e)
{
this.Close();
}
How do I get the main form to show?
ShowDialog opens your secondary Form as Modal Dialog, meaning that the MainForm's code execution will stop at that point and your secondary Form will have the focus. so all that you need to do is put a this.Show after your ShowDialog call.
From above link:
You can use this method to display a modal dialog box in your application. When this method is called, the code following it is not executed until after the dialog box is closed.
private void countClick(object sender, EventArgs e)
{
this.Hide();
subForm myNewForm = new subForm();
myNewForm.ShowDialog();
this.Show();
}
Let's say in Form1 you click a Button to show Form2
Form2 frm2 = new Form2();
frm2.Activated += new EventHandler(frm2_Activated); // Handler when the form is activated
frm2.FormClosed += new FormClosedEventHandler(frm2_FormClosed); // Hander when the form is closed
frm2.Show();
Now, this one is when the Form2 is shown or is Activated you hide the calling form, in this case the Form1
private void frm2_Activated(object sender, EventArgs e)
{
this.Hide(); // Hides Form1 but it is till in Memory
}
Then when Form2 is Closed it will Unhide Form1.
private void frm2_FormClosed(object sender, FormClosedEventArgs e)
{
this.Show(); // Unhide Form1
}
This is difficult to do correctly. The issue is that you must avoid having no window at all that can get the focus. The Windows window manager will be forced to find another window to give the focus to. That will be a window of another application. Your window will disappear behind it.
That's already the case in your existing code snippet, you are hiding your main window before showing the dialog. That usually turns out okay, except when the dialog is slow to create. It will definitely happen when the dialog is closed.
So what you need to do is hide your window after you display the dialog and show it again before the dialog closes. That requires tricks. They look like this:
private void countClick(object sender, EventArgs e)
{
this.BeginInvoke(new Action(() => this.Hide()));
using (var dlg = new subForm()) {
dlg.FormClosing += (s, fcea) => { if (!fcea.Cancel) this.Show(); };
if (dlg.ShowDialog() == DialogResult.OK) {
// etc...
}
}
}
The BeginInvoke() call is a trick to get code to run after the ShowDialog() method runs. Thus ensuring your window is hidden after the dialog window is shown. The FormClosing event of the dialog is used to get the window to be visible again just before the dialog closes.
You need to find some way to pass a reference to the main form to the second form click event handler.
You can do this either by setting the form as a member variable of the second form class or pass it via the event arguments.
If you are working in the same namespace, you have the context, using mainform or the name you gave the "main form", try:
mainform.show();
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();
}
Here's the XAML code:
<Application x:Class="WpfApplication2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup" />
Backing code:
using System.Windows;
namespace WpfApplication2
{
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
new Window().ShowDialog();
new Window().ShowDialog();
}
}
}
Window shows only one time and then application exits. Why??
UPDATE: I know that windows should show up consequently. But after I close first window second does not show up at all
Try this
private void Application_Startup(object sender, StartupEventArgs e)
{
var w1 = new Window();
var w2 = new Window();
w1.ShowDialog();
w2.ShowDialog();
}
Paste form comment:
I think when you close first window,application checks whether there are other windows,and it doesn't find any (so application is closing), because second window haven't been created
Am I right to say that this will show the two windows consecutively and not simultaneously? When window1 is closed window2 will automatically open as the call is ShowDialog() which opens the window and then sets focus to it and doesn't open the other one until window1 is closed?
You can use a for loop to do so. Howerver, I have no idea why can't call directly.
for (int i = 0; i < 2; i++)
{
new Window().ShowDialog();
}
You are possibly ending the entire application in the Code used to close Window 1. If you are using something like Environment.Exit(0); this could be the issue.
ShowDialog wont allow you to create a same form unless its closed.
It's the difference between a modal and modeless form.
I think WPF is as the same reason...
and you can see ↓
Display Modal and Modeless Windows Forms
UPDATE:
Take a test by Stecya's answer , and it work fine...
protected override void OnStartup(StartupEventArgs e)
{
var w1 = new Window();
var w2 = new Window();
w1.ShowDialog();
w2.ShowDialog();
}