Switching from one window to another in WPF and making it active - c#

I'm pretty new to WPF and I'm trying to make a database system. What I currently have is a Login Window. When you enter the user and password you are supposed to go to another window StudentInfoSystem . The code I used is pretty basic and common.
var info = new StudentInfoSystem.MainWindow();
info.Show();
this.Close();
So, what this would do, is after you press the login button, you get transferred to StudentInfoSystem and the login window closes. The problem I have with Show() is that it opens a window and immediately returns, right? It doesn't wait for the new window to close. So, my question is how can I open a new window and WORK with it? When I say work, I meant to show out information in my textboxes (In the NEWLY opened window) depending on the role the user has, etc...

I'm guessing the above code is in the button click handler for the Login Window, which would make the Login Window the parent of the StudentInfoSystem window.
Since WPF will close the parent and any child(ren) window(s) when closing the parent window, your StudentInfo window will also close when calling
this.Close();
One option might be to instead call
this.Hide();
but without seeing how the rest of your app is set up, not 100% sure this is the best approach.
Perhaps see these SO questions:
wpf-create-sibling-window-and-close-current-one
how-to-close-current-window-in-code-when-launching-new-window

Try window.Activate() to focus the new window and/or [any element].Focus() to focus any element within window.

As I understand, this should do what you want:
info.ShowDialog();
You could also check ShutdownMode property. I would rather say, login window is sth you want to close after login, but do what you want :). Usage of ShutdownMode property:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
this.ShutdownMode = System.Windows.ShutdownMode.OnLastWindowClose;
}
}

Related

How to implement a login/register flow in windows phone 8

I'm trying to implement the login/register/forgot password flow for my first app in windows phone.
The idea main points of the result are:
The login form is accessible from many points of the app, when the user attempts to make an action that requires him to be logged in the system.
The login form must show the "register" option, showing a new screen with the register form
When the user closes the register form must return to the login form
A) I explored the Add/New Item menu in Visual Studio and the Content Dialog seems to be prepared for that functionallity, since its template xaml is a login screen. So I created a LoginDialog and a RegisterDialog from the ContentDialog template. Am I right?
B) The "sign in" button closes immediatly the Dialog, whats is the common pattern to make the user wait while the request is sent across the network and show the possible errors that may happen
C) How should I implement the navigation between ContentDialogs by the way I added a button to the LoginDialog:
private async void RegisterButton_Click(object sender, RoutedEventArgs e)
{
this.Hide();
await new RegisterDialog().ShowAsync();
}
How can I make the RegisterDialog to return to the Login dialog on close?
D) The dialog get closed when I press the Primary or Secondary button. How can I avoid it to close to show validation errors (like invalid password)
In my application I implemented it by putting both the Sign in option and the Register option on a MessageDialog, which is shown when the user tries to log in, so you don't need to put the Register option on the Sign in page.
I added separate pages, not content dialogs. I think it's a better approach, because this way if you get an error, the page won't "close", like a ContentDialog does, and you can handle the navigation very easily with simple GoBack and Navigate calls.

Avoid Focus on Mainwindow when showing it

I'm currently working on a popup program in wpf that gets hidden either by this.hide(); or MainWindow1.WindowState = WindowState.Hidden and "pops up" using MainWindow1.WindowState = WindowState.Normal;
My problem is, that I don't want the Mainwindow to gain any keyboard focus.
So whatever program has the keyboard focus, when the popup gets shown, it should keep it.
I just want it that way, so people don't type entire emails in the not handeling Popup, just because they didn't notice it popping up.
Edit:
I'm not trying to keep focus in any my own program windows but in other windows programs (e.g. Outlook)
Edit2:
Here is a screenshot from my Program, just to clear obscurities about the usage of the PopUp class.
Edit3: Maybe it's possible to set the keyboard focus back to the programm that was focused before?
so people dont type entire emails in
I would recommend that you set the main page controls, or their container, Enabled property to false when the popup is running and reverse when it is not. Hence focusing the user to the popup until its acknowledged.
If you purpose is to show a notification form, check that component: Windows Forms Toolkit NotificationForm
The solution is (as it seems) too easy, all you need to do is:
MainWindow1.Showactivated = false;
this.Show();
This will show the MainWindow while the focus is kept on whatever program had the focus before the MainWindow appeared.

Open a dialog in the same window and wait for user input

Is there a way to open a new window instance within the primary application window and still wait for a user response before continuing with the main program? I just have a 3 option query with a picture to be offered to the user and a whole new window opening up seems like overkill, I would much prefer it opening in a frame within the current window.
Do something like this sans the separate window:
OptionWindow optionDialog = new OptionWindow();
optionDialog.Owner = this;
optionDialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
optionDialog.ShowDialog();
if (optionDialog.DialogResult == true)
{
something;
{
Seems like you could just have your "OptionWindow" be a frame that is on the WPF form, and when you want to show it, just disable all other panels and show the frame with your dialog, and after the user completes the dialog, enable all other panels and hide your dialog frame.
After I posted my answer, I saw that Mark Hall made an edit to his comment with pretty much the same suggestion. Sorry Mark.
I guess you are looking for modal window which can be achieved using Window.Showdialog.
Opens a window and returns only when the newly opened window is
closed.

Why calling Hide in a child form's FormClosing event handler hides the parent form?

When Form2 is closed, via it's X button, the Main form is sometimes hidden as well, but not always. Often times the Main form is hidden after initial 'newForm' button click and other times many open-close operations are required before the Main form gets hidden on Form2's closing. Why is this happening? Why is it irregular?
This is a small test code for a larger application I'm working on. In that application a thread continuously reads the network stream and when a particular message is encountered a modal form is displayed. The user can close that modal form or it can be told to close itself by a different network message. In this event, to give the user some time to view the data that the form is displaying I implemented a delayed form closing for that form. When the form is running its delay closing code, another message can come in over the network that will open up a new instance of this form in which case, I observed, that once the timer of the original form runs out, the original form is left displayed until the new instance is closed. Calling Hide in the FormClosing event handler closes the original form if more than one instances of it are running, but it has this side effect of hiding the entire application (the Main form) when the last instance of this form is closed, either by the user or by the delayed closing code. And again, the entire application is not always hidden, but it does happen.
//Main form's 'newForm' button
private void btn_newForm_Click(object sender, EventArgs e)
{
Form2 f = new Form2();
f.ShowDialog();
}
public partial class Form2 : Form
{
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
Hide();
}
}
Update (from the application I'm working on):
The problem is shown visually below. The top part of the picture, labeled "A", represents the situation where the first modal dialog (greyed out) was instantiated and it is in the process of being auto closed after 4 seconds have elapsed. The second instance (blue window heading) is active and awaiting input. In the lower part of the picture, labeled "B", the counter to closing of the first instance has completed, yet the first instance remains visible. Adding Hide does not change picture "A" but picture "B" would only be showing the active modal dialog, which is what I want. If Hide is not used and we have the case shown in "B", once the active modal dialog is closed the inactive dialog will disappear together with the active one, but no sooner. At this time my main form will be hidden as well, sometimes.
Your main form doesn't get hidden, it disappears behind another window. The flaw in your code is that for a brief moment none of your windows can get the focus. Your main window can't get the focus, it got disabled by your dialog and won't get re-enabled until the dialog is fully closed. Your dialog can't get the focus, you hide it. So Windows goes looking for another window to give the focus to and can only pick a window owned by another application. Like Visual Studio, nice and big so your main window is well covered by it.
Not sure what you are trying to do, it doesn't make sense to call Hide() since the dialog will close a couple of microseconds later. Just delete the statement.
I am not sure if I am right but maybe you forgot to add e.Cancel = true; to your closing event.
Second, I think using a modal form is only usefull when you expect an action like OK or CANCEL from user, that is where DialogResults comes handy. It sounds strange if this happens time to time not all the time! maybe you can try like this:
//Main form's 'newForm' button
//Define form in your mainform
private Form2 f;
private void btn_newForm_Click(object sender, EventArgs e)
{
if(f != null) { f.Show(); return; }
f = new Form2()
f.FormClosing += delegate { f.Hide(); };
f.Show();
}
I know the topic is quite old, but I recently had to look for answers for this precise question.
Why hiding the (child modal) form instead of closing it ?
I may be wrong, but I think that in some cases, hidding the modal child form instead of closing it is sometimes useful.
For example, I'm using a class that is a custom tree of grids. Think of something like an Excel Document with multiples tables (sheets) and each table can have child tables. A very powerful manner to store datas that can be used by multiple objects and multiple forms at a time.
Now, this "TreeTable_Class" object has an inbuilt custom form that actually shows the content of one of its tables at a time in a GridView, and you can select which table to show by selecting it in a Treeview. You can see here that the "Database Editor" is actually and MDI Form that can load the Form from any TreeTable_Class.
And this is the Form I use to edit the content of a Cell for a given (selected) Table (I've chosen another cell with long text content from another table in this database)
Now, when you choose to close the custom form instead of hiding it, that form will be unaccessible, you can't show it anymore, and you get an exception (no instance of the object) Somewhat, it isn't disposed yet (so the check If MyForm Is Nothing Then... is useless) I know I have to implement the GarbageCollector and dispose the Child Form manually, but it's outside the scope of this topic.
Anyway, my class could use a large amount of memory, of datas, and if I had to rebuilt ALL the contents each time I want to show a new instance of that form, that would be a large amount of workload in my application. That's why I have chosen to hide the form instead of closing it until the main application exits or when a specific CloseFormAndDispose() method is explicitly called, either by the program, or if I make this option available for the user via an user interface.
Workaround try :
This is the workaround I've found to override the "form replaced by another because none of the parent/child ones could be retrieved" :
Sorry, I'm in VB.. but you can use a tool to convert this to C#, or do it manually, it's pretty simple..
// This is the child, a Cell Editor that can edit the content of a Cell.
Protected WithEvents _CellEditor As CellEditor_Form = Nothing
This Editor form is a member of TreeTable_Form, a form that can actually show and edit the content of the whole Database File (a single file)
And this TreeTable_Form class contains a routine that handles CellEditor closing event
Public Partial Class TreeTable_Form
// Sorry. The "WithEvents" in C# is a litte bit complex to me... So, in VB :
Protected WithEvents _CellEditor As CellEditor_Form = Nothing
// ...
// CellEditor handling method (I used a Code converter...) :
// The original VB declaration is :
// Protected Sub RecallFormAfterCellEditorHidden() Handles _CellEditor.Closed
// You'll have to write specific Event handler for _CellEditor object declared above...
protected void RecallFocusAfterCellEditorHidden()
{
Application.DoEvents();
this.Focus();
}
End Class
This tiny protected void RecallFormAfterCellEditorHidden() method in your Class (if you are using a class that contains Forms) or in your Main From, assuming that your main form contains the child forms (dialogs) will try to force the focus on your Application or MainForm...
By the way, TreeTable_Form is actually a component of TreeTable_Class. The later is an object that can be used anywhere you want. In a Main Form Application, in another Class, in a dialog, anywhere... and could be passed by reference to share its contents between several items. And this TreeTable_Class contains a RecallFocusAfterTreeViewerHidden() method that handles the closing of that form. That means, the Form or Application that actually uses the class will get the focus each time you close the its child Form. I've made it that way to get an object that could be used anywhere
We still get problems !
However, this method will make your application flicker a bit each time you close your child dialog, and doesn't succeed at 100% ! Sometimes, my parent form still disappear from screen and gets struck behind another window. Alt+TAB wont helt either. But this happens less than without this method trick. I don't have any better answer at this time, still searching... I'll come back here if I find out how. I'm using this custom made application in my work to write memos during meetings for example, and produce PV (procès verbal - french sorry) in PDF or DOCx on the fly...
And I'm sorry, I'm in VB, not C#. Hope this helps a little, until we find a better workaround for this...

How do you send information from one window to another in the same program?

In the program I am trying to build, I have a menu button that opens a second window. The user puts information into the second window, presses the "Done" button, and the information is transfered into the main window. The problem I am having is opening the second window. I have both windows build in xaml files in Visual Studio but I can't find a way to show the second window. Using "Window window = new Window" does not fit my needs because 1) I already have the second window built and 2) I have tried this and I cannot figure out how to add children to the window; there is no window.children nor any grid to put the children into. Thank you in advance!
Moments after I pressed post, I thought of something I hadnt tried:
"WindowAdd add = new WindowAdd; //WindowAdd being the second window
add.Show();"
This does exactly what I want it to do. The next problem I have is sending the information the TextBoxes into the MainWindow. I am thinking cookies might work but am unsure. Anyone have any thoughts? Thanks in advance!
You need to create the Window in code, but instead of doing:
Window window = new Window();
You should use:
Window2 window = new Window2(); // Assuming the window's class name is Window2
This will construct and initialize an instance of your new window class, defined in XAML. Once you've done this, you can open the window and you'll see all of your controls.

Categories

Resources