WPF Multiple dialogs, Visibility property issue - c#

I have a login form which starts a dialog of a lecturerWindow
When swapping windows it looks like that:
//LoginWindow to LecturerClient
this.Visibility = Visibility.Collapsed;
LecturerWindow lecturerClient = new LecturerWindow(self);
lecturerClient.Owner = this;
lecturerClient.ShowDialog();
this.Visibility = Visibility.Visible; // so when the lecturerClient dialogs exits - the login form will be visible
And also my LecturerWindow opens another dialog:
//LecturerClient To Session
Dispatcher.Invoke(() =>
{
Visibility = Visibility.Collapsed;
Session newSession = new Session(mySelf, Courses.Find(item => item.courseId == courses[1].ToString()));
newSession.Owner = this;
newSession.ShowDialog();
Visibility = Visibility.Visible;
});
The issue begins when my Session dialog closes and suddenly both my LoginWindow and my LecturerWindow goes Visible, it's like my LoginWindow thinks the session closing is the lecturerWindow closing
Thank you in advance!

I'm sure you have solved your issue already, but here's a solution for future readers:
Instead of hiding the windows in the app by setting window.Visibility = Visibility.Collapsed;, I would simply open the new window and then close the old window:
// in LoginWindow.xaml.cs
private void SubmitButton_OnClick(object sender, RoutedEventArgs e)
{
// create a new window to show
LecturerWindow newWindow = new LecturerWindow()
{
Title = "Lecturer Window",
WindowStartupLocation = WindowStartupLocation.CenterScreen
};
// change the app main window to use the new window
Application.Current.MainWindow = newWindow;
newWindow.Show();
// close the LoginWindow
this.Close();
}
Note that if you close the current window before opening the new one, if there are no other windows open, the application will initiate shutdown. This behavior is determined by the Application.ShutdownMode property. By opening the new window before closing the current we avoid this (like shown above).
The same can be done in your LecturerClient to open the Session window.
When closing the LecturerClient window you can open a new LoginForm window again by subscribing to the Closing event:
// in LecturerWindow.xaml.cs
public LecturerWindow()
{
InitializeComponent();
Closing += OnClosing;
}
// Open the login form again when this window is closing
private void OnClosing(object sender, CancelEventArgs e)
{
// create a new window to show
LoginWindow newMainWindow = new LoginWindow()
{
Title = "Login form window",
WindowStartupLocation = WindowStartupLocation.CenterScreen
};
// change the app main window to use the new window
Application.Current.MainWindow = newMainWindow;
newMainWindow.Show();
// This window is already closing, so we don't need to call Close()
}

Related

how to open a window from a window exist

I have a main window, inside there is a button which in a click-
open a dialog window to write a name save a name in a textbox and need to open another window.
I want it will open the new window at the main window-
but it is opened the window in the dialog window, allthoght I set the Owner to be the main window..
what should I do?
this is the code in a button of the dialog window:
Screen myScreen = new Screen (name, ViewModel, mainWindow);
myScreen.Owner = mainWindow;
myScreen.Show();
this.Close();
This is how you should do it:
In your first dialog, you must have a public variable,something like:
public string TextBoxContent;
And in the OK button event, you'll do something like:
this.TextBoxContent = TextBox.Text;
this.DialogResult = true;
this.Close();
In your main window you must do this:
string returnedString;
DialogWindow w = new DialogWindow ();
w.ShowDialog();
if (w.DialogResult.HasValue && w.DialogResult.Value)
returnedString=w.TextBoxContent;
And after that, you'll show your second dialog with the returned string. Hope you see the logic.
Ok you have three windows one is MainWindow which have a button to open another window name Dialog which have a textBox for input name and a button for pass that textBox input to another window name Screen. SO I have take a textBox in Screen window named textBoxName which will show the passed text, here is my solution
the main window button show dialog this way
private void buttonMainShowDialog_Click(object sender, RoutedEventArgs e)
{
Dialog dl = new Dialog();
dl.ShowDialog();
}
Constructor for Screen window as below which take text as a parameter by which we pass the Dialog window textBox text
public Screen(string text)
{
InitializeComponent();
this.textBoxName.Text = text;
}
and you need to call this screen window from dialog window as below
private void buttonDialogShowScreen_Click(object sender, RoutedEventArgs e)
{
Screen myScreen = new Screen(this.textBox.Text);
myScreen.Show();
this.Close();
}
its works fine, hope this help you

this.Close(); doesn't work in window wpf

In wpf, window I am calling window forms. Before calling that I just want to close that window. Here is my code.
public partial class MainWindow : MetroWindow
{
public MainWindow()
{
InitializeComponent();
}
private void BtnIntroClick(object sender, RoutedEventArgs e)
{
PdfReader form = new PdfReader(1);
form.ShowDialog();
this.Close();
}
}
No error, but form is not closing.
And in window form also, this.Close() in not working
public partial class PdfReader : Form
{
public PdfReader(int page_num)
{
InitializeComponent();
var executingFolder = System.AppDomain.CurrentDomain.BaseDirectory;
var dbPath = System.IO.Path.Combine(executingFolder, "BiodermaProduct.pdf");
axAcroPDF1.LoadFile(dbPath);
axAcroPDF1.setCurrentPage(page_num);
}
private void PdfReader_FormClosed(object sender, FormClosedEventArgs e)
{
this.Opacity = 0;
MainWindow w = new MainWindow();
w.ShowDialog();
}
}
It will close when you close your PdfReader form. Form.ShowDialog returns only when the form is closed. So this.Close() is not called until ShowDialog finishes.
What you can do is set this.Visibility = Visibility.Hidden before calling form.ShowDialog();
Important detail that we need to bear in mind when we deal with windows closure and other UI operation: we need to execute it in UI thread only.
This is exactly that happened in my case.
I raised an event from the server and when it happened I raised another event through custom Event Aggregator to close the second Window that is opened (without shutting down the application).
However it didn't happen without an error or visible reason. My window was still opened.
Nevertheless, when I enabled "Common Language Runtime exception" through visual studio settings:
I caught the exception: "Full Exception: System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.Window.Close().........."
Consequently, instead of this:
ServiceLocator.Current.GetInstance<IEventAggregator>().GetEvent<ServerDisconnectedEvent>()
.Subscribe(e => Close());
Run this:
ServiceLocator.Current.GetInstance<IEventAggregator>().GetEvent<ServerDisconnectedEvent>()
.Subscribe(e => Application.Current.Dispatcher.BeginInvoke(new Action(Close)));
I hope this will safe time for someone like me :)
If you read this MSDN article you'll see that ShowDialog only returns when said window is closed. This means your code is blocked on that line until the window is closed. You have to close your current window first, then ShowDialog.
private void BtnIntroClick(object sender, RoutedEventArgs e)
{
PdfReader form = new PdfReader(1);
this.Close();
form.ShowDialog();
}
Note that Show does not work in this way.
When You use Window.ShowDialog(), it calls new Window modally, meaning you cannot go to the parent form.
The Window.Show() function shows the form in a non modal form. This means that you can click on the parent form.
However, this code will close your application as MSDN says(thanks to #Empereur Aiman):
A ShutdownMode of OnMainWindowClose causes Windows Presentation
Foundation (WPF) to implicitly call Shutdown when the MainWindow
closes, even if other windows are currently open.
And you should set your ShutdownMode to OnLastWindowClose as MSDN says:
If you set ShutdownMode to OnLastWindowClose, Windows Presentation
Foundation (WPF) implicitly calls Shutdown when the last window in an
application closes, even if any currently instantiated windows are set
as the main window (see MainWindow).
Just reorder your call of ShowDialog():
PdfReader form = new PdfReader(1);
this.Close();
form.ShowDialog();
or:
PdfReader form = new PdfReader(1);
form.Show();
this.Close();
and set ShutdownMode="OnLastWindowClose" at App.xaml file of your application:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
ShutdownMode="OnLastWindowClose"
>
</Application>
You code is:
PdfReader form = new PdfReader(1);
form.ShowDialog();
this.Close();
It means CLR executes modally your new PdfReader window. That is, execution of your program goes to PdfReader window. And only after closing PdfReader window, CLR executes your next row:
this.Close();
and your MainWindow() will be closed.
You need to change the order between this.Close(); & form.ShowDialog(); and it will work well
Try this code:
private void BtnIntroClick(object sender, RoutedEventArgs e)
{
PdfReader form = new PdfReader(1);
this.Close();
form.ShowDialog();
}

How to open a same window as childwindow and when closed enable parent window?

I have a window that opens a pop up and what i want is open the popup as child window or window on top of another and disable the back window? so that somebody cannot go back and close the Main window.
I tried putting the window top most but still i am able to close the main window.
private void axWebBrowser1_NewWindow3(object sender, DWebBrowserEvents2_NewWindow2Event e)
{
BrowserWindow window = new BrowserWindow();
window.axWebBrowser1.RegisterAsBrowser = true;
window.Visibility = Visibility.Visible;
window.textBox.IsEnabled = false;
window.Height = 550;
window.Width = 600;
e.ppDisp = window.axWebBrowser1.Application;
window.Topmost = true;
}
Does setting the owner of the child window help?
private void axWebBrowser1_NewWindow3(object sender, DWebBrowserEvents2_NewWindow2Event e)
{
BrowserWindow window = new BrowserWindow();
window.Owner = this;
...
}
When you display the child window, display it as a modal window, using the
Form.ShowDialog Method. There's no need to disable the parent window then, as the child window being shown as a modal window would make the parent window not accessible until the modal window is closed.
BrowserWindow window = new BrowserWindow();
window.ShowDialog();
If modal doesn't work for you for some reason try something like this. I'm unsure of why you can't use modal, need to understand your requirement a little more.
private void axWebBrowser1_NewWindow3(object sender, DWebBrowserEvents2_NewWindow2Event e)
{
BrowserWindow window = new BrowserWindow();
// in your case I think the parent form should be = this.
Form parentForm = this;
window.Tag = parentForm;
window.FormClosing += new FormClosingEventHandler(this.BrowserWindow_FormClosing);
parentForm.Enabled = false;
}
private void BrowserWindow_FormClosing(object sender, FormClosingEventArgs e)
{
Form parentWindow = (sender as Form).Tag;
parentWindow.Enabled = true;
}

reloaded wpf window

I have main wpf window, in this window I create new slave windows and add in dictionary. It is possible, after closing the slave window, it showed once again.
public class MainWindow:Window
{
private dictionary<string, SlaveWindow> _winDic= new dictionary<string, SlaveWindow>();
public void SomeMethod()
{
var mySlaveWindow = new SlaveWindow();
//add to dictionary
_winDic.Add("mySlaveWindow",w);
//close slave window w
//show
_winDic[mySlaveWindow].Show();
}
}
This following way of doing this is taken from this msdn page.
Subscribe to the Closing event for the Window and add this in code behind.
private bool m_close = false;
// Shadow Window.Close to make sure we bypass the Hide call in
// the Closing event handler
public new void Close()
{
m_close = true;
base.Close();
}
private void Window_Closing(object sender, CancelEventArgs e)
{
// If Close() was called, close the window (instead of hiding it)
if (m_close == true)
{
return;
}
// Hide the window (instead of closing it)
e.Cancel = true;
this.Hide();
}
This will make sure your Window finally closes and is not left hanging.
You'll need to hide the window rather than closing it.
If you call Hide(), the window will vanish like it would when you call Close() but you'll be able to reshow it later by calling Show() again.

ShowDialog() doesn't bring form to top when owner is minimized

ShowDialog() doesn't bring form to top when the owner is minimized. It is shown and visible, but it is not focused and behind the current window. Even using the commented lines, I see the issue.
public void Form1_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
// this.Hide();
using (var f = new Form1())
{
// this.WindowState = FormWindowState.Normal;
f.Text = "ShowDialog()";
f.Click -= new EventHandler(f.Form1_Click);
f.ShowDialog(this); // f is not on top?
this.Show();
}
}
this.WindowState = FormWindowState.Minimized;
As soon as that executes, there is no window left in your application that can still receive the focus. Windows needs to find another one to give the focus to, it will be a window of another app. A bit later your dialog shows up, but that's too late, focus is already lost.
Using a trick like Control.BeginInvoke() to minimize the form after the dialog is displayed doesn't work either, the dialog automatically closes when it parent minimizes. The best you can do is hide it. You'll have to use the same trick to restore it before the dialog closes or you'll still lose focus. Like this:
protected override void OnClick(EventArgs e) {
using (var f = new Form1()) {
f.Text = "ShowDialog()";
this.BeginInvoke(new Action(() => this.Hide()));
f.FormClosing += delegate { this.Show(); };
f.ShowDialog();
}
}

Categories

Resources