I have several windows (MainWindow, Window1, Window2) in WPF application
Every window has a button that shows next window (MainWindow -> Window1 -> Window2) in modal mode. Something like:
MainWindow Button Handler
Visibility = Visibility.Hidden;
Window1 w = new Window1();
w.ShowDialog();
Visibility = Visibility.Visible;
Window1 Button Handler
Visibility = Visibility.Hidden;
Window2 w = new Window2();
w.ShowDialog();
Visibility = Visibility.Visible;
The problem is - when Window2 is closed (Alt + F4) not only Window1 ends it "w.ShowDialog()" method call, but MainWindow too! When Window2 is closed - both windows (Window1 + MainWindow) become visible simultaneously!
Why MainWindow becomes visible and what can I do to avoid this?
Thank you in advance!
If you hide the windows, you might as well use the Show() method and handle the Closed event instead of calling ShowDialog():
Visibility = Visibility.Hidden;
Window1 w = new Window1();
w.Closed += (ss, ee) => Visibility = Visibility.Visible;
w.Show();
This should solve your issue.
Related
I have two windows. Main Window & Window1.
On Main Window, there is a button1. When it is clicked, it gets disabled and open Window1. But i want to enable button1 on Main Window when Window1 is closing or get closed.
Create A Public Button in Window1
public Button mainBtn ;
on mainWindow in the button click event
private void button_click(object sender , RoutedEventArgs e){
Window1 win = new Window1();
this.button.IsEnabled = false;
win.mainBtn = this.button;
win.Show();
}
add on closing event to Window1
private void Window_closing(object sender , CancelEventArgs e){
mainBtn.IsEnabled = true;
}
the idea is to pass the MainWindow Button to the Window1 Button
then you can control it as like you want .
I guess you are using WinForms. In that case you have an event handler for the click on button1:
private void OnButton1Clicked(object sender, ...)
{
// show window 1
}
Now there are two methods to show a Form. You can show it as a modeless dialog box or as a modal dialog box.
Modal dialog boxes, which require the user to respond before continuing the program
Modeless dialog boxes, which stay on the screen and are available for use at any time but permit other user activities
Most dialog boxes you see are Modal: If you press file save, you'll have to finish the Save-File-Dialog box before you can continue editing.
The modal dialog box is the easiest
- Show them using using Form.ShowDialog.
- ShowDialog returns when the form is closed.
If you use a modal dialog box your code would look sequential:
private void OnButton1Clicked(object sender, ...)
{
using (Window1 window1 = new Window1())
{
// if needed window1.SetValues...
var dlgResult = window1.ShowDialog(this);
// if here, window 1 is closed
if (dlgResult = DialogResult.OK)
{ // ok button pressed
// if needed: window1 read resulting values
}
} // because of using window 1 automatically disposed
}
However if window1 is shown as a modeless dialog box, window1 will have to tell others that it is closed. Use event Form.Closed:
private Window1 window1 = null;
private void OnButton1Clicked(object sender, ...)
{
if (this.window1 != null) return; // window1 already shown
this.window1 = new Window1())
this.window1.Closing += this.OnFormClosed;
}
private void OnFormClosed(object sender, FormClosedEventArgs e)
{
Debug.WriteLine("window1 closed");
if (this.window1.DialogResult = DialogResult.OK)
{
// process dialog results
}
this.window1.Dispose();
this.window1 = null;
}
Data Binding is the strongest tool in WPF:
Add the button and bind the IsEnabled property to a public property in your view model or code behind. In the secondary window - when closing - update the property to reflect the new state.
Do not forget to implement INotifyPropertyChanged
I have the following code in App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
var window = new WelcomeWindow();
if (window.ShowDialog() == true)
{
var mainWindow = new MainWindow();
mainWindow.ShowDialog();
}
}
The second window never shows. Instead, the application simply closes when the Welcome window is closed. How do I ensure a second window can be shown after a first one is closed?
This is because default value of Application.ShutdownMode is OnLastWindowClose. This means when your WelcomeWindow is closed the application shuts down and you see nothing more.
To solve this set ShutdownMode to OnExplicitShutdown and call Shutdown explicitly if you want to exit your app.
public App()
{
this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
}
What about to show WelcomeWindow on Initialized event of MainWindow and close last if Dialog is not true. This was you let MainWindow to stay the MainWindow of Application.
private void Window_Initialized(object sender, EventArgs e)
{
// at this moment MainWindow is Initialized but still nonvisible
if ((new WelcomeWindow()).ShowDialog()!=true)
{
this.Close();
}
}
When you load any window Application_Startup it become The MainWindow of application. And it will closed on this window closing.
I've checked that even if you have StartupUri="MainWindow.xaml" in you app.xaml it have no effect if some else window have been shown on Application StartUp event.
You may do it yourself. Just make breakpoint on your firstloaded window Loaded event handler and look in debuger on "Aplication.Current.MainWindow == this" expression result. It will be true.
private void btnConfirmInMyForm_Click(object sender, RoutedEventArgs e)
{
//for example without creating like this
MainWindow mainWin = new MainWindow();
mainWin.txtBirthDate.Text = "anything";
this.close();
}
when i try the above, content of the txtBirthDate of new instance of MainWindow (mianWin) changes to "anything", but not in current MainWindow!
in other words as i click btnConfirmInMyForm in MyForm it opens a new MainWindow with the txtBirthDate textBox contains "anything", which i don't want!
i only want to set the txtBirthDate from MyForm, not to create a new MainWindow that contains this!
with best regards
Is btnConfirmInMyForm_Click within your window? Then just try
this.txtBirthDate.Text = "anything";
If your MainWindow is the Application's MainWindow, then you could try something like:
private void btnConfirmInMyForm_Click(object sender, RoutedEventArgs e) {
var mainWindow = Application.Current.MainWindow as MainWindow;
if (mainWindow != null)
mainWindow.txtBirthDate.Text = "anything";
}
If it isn't you'd could pass your MainWindow object to the other Window to then use that object and assign the Text. You could also use something like a messaging pattern from MVVM to send messages across Views. There are quite a few options. What you pick is pretty much upto you.
So I have a user control within a window. I need to be able (from user control) to retrieve the parent window left and top (in order to locate a new popup I'm opening from the child). I'm trying to do this by referencing the UserControl .Parent property but doesn't seem to work.
Any idea? Thanks!
Are you using MVVM? Are you concerned about writing code in the code behind? .Net 3.5 or 4.0?
From the UserControl Code behind you could use:
Window parentWindow = Window.GetWindow(userControlReference);
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
Loaded += new RoutedEventHandler(UserControl1_Loaded);
//Window parrentWindow = Window.GetWindow(this);//don't add here the value will be null
}
void UserControl1_Loaded(object sender, RoutedEventArgs e)
{
Window parrentWindow = Window.GetWindow(this);
}
}
I'm sure this is something very simple but I can't figure it out. I've searched here and on msdn and have been unable to find the answer. I need to be able to set the richtextboxes selection via richtextbox.Selection.Select(TextPointer1, Textpointer2).
Application.Current contains a collection of all windows in you application, you can get the other window with a query such as
var window2 = Application.Current.Windows
.Cast<Window>()
.FirstOrDefault(window => window is Window2) as Window2;
and then you can reference the control from your code, as in
var richText = window2.MyRichTextBox
Application.Current.Windows.OfType(Of MainWindow).First
You should be able to access controls on Window1 from Window2 code behind, if that's what you want. Generated fields are internal by default.
All you need is to name the control on Window1, like this:
<RichTextBox x:Name="richtextbox" ... />
In Window2 code behind:
var window = new Window1(); // or use the existing instance of Window1
window.richtextbox.Selection.Select(TextPointer1, Textpointer2);
A better option would be to encapsulate select operation in a method in code behind of Window1, to avoid giving away internal. Then you would have:
// Window1.cs
public void Select(int param1, int param2)
{
richtextbox.Selection.Select(param1, param2);
}
// Window2.cs
var window = new Window1(); // or use the existing instance of Window1
window.Select(TextPointer1, Textpointer2);
You cant access the texbox from another window as it is private to that window you can however work around this by exposing the RichTextBox as a public property on your window (hack)
public RichTextBox RichTextBox {
get{
//the RichTextBox would have a property x:Name="richTextbox" in the xaml
return richTextBox;
}
}