views:

53

answers:

2

First of all, we are in C#, WPF, desktop application (can be .NET 3.5).

I need to show login window when application starts, if login succeeds, hide login window and show main app window. In addition, when the main window is closed, one should see login window again. If login window is closed, application quits.

Bonus to make it harder: when "Remember user" option checked, login window is skipped and user is logged in automatically, showing the main window instatly. (please do not think about how the option is stored, assume you just know it and have the value in variable).

What is meant to be the application startpoint (means which window is considered to be in app.xaml StartupUri property)?

How would you solve architecture? Is the best way to use App_Startup event and show some window from that point?

What type of App.ShutdownMode would you use? And how would that work? You can use "OneLastWindowClose", "OnMainWindowClose" or "OnExplicitShutdown". What is your choice and why?

In general, I am interested in "what calls what, what is application 'root', what invokes closing the application".

I already have a solution for my problem that works, but I am interested, if any of you have met this problem and how have you solved it? I will gladly share my approach, but I don't want to limit your ideas in the first place.

Thank you for your contribution.

P.S.: I am using MVVM framework, that makes it just a little more messy, but the point stays. I also use Ninject as IoC, but this issue still of course stays on. I did not mention these information to make the question as clear as possible. I also have to handle exceptions (communication with server or db during the login may fail), and to make it really interesting, I must show interactive 'splashwindow' indicating what application does (loading, communication with server, autologin). But please stay away from these requirements at the moment, we can discuss them later.

+1  A: 

I'm going to repeat your questions as I understand them, you can correct me where I am missing something. Also, I'm rather new to the whole M-V-VM thing, so take my advice with a grain of salt. The best way I know how to learn is to throw out my ideas and have them corrected.

You want to know things 1) Where should the logic exist to decide where to show the login or main window 2) Which shutdown mode to use 3) What is application root

1) I believe the decision to show a login or auto login is business logic, thus should live in the Model of your M-V-VM framework. Once that logic is implemented, the view can display whichever window is required by querying the Model.

I assume your application has an App.xaml and App.cs file which runs when the application is executed. You can override OnStartup within App.cs and display whichever window is necessary, based on the results of the business logic (which are learned from using some object in your Model).

2) For shutdown model, I'd probably go with OnLastWindowClose, but I have no idea how many windows your application is using. I assume only the two you mentioned (login and main).

3) What is application root? I would argue that your Model is really the application root, in that it holds all of the important stuff (view is user interface to the model, view model is state for the view). So, when it comes to what is the root or essence of your application, I would argue it is some set of objects in your model.

What calls what? That will all depend on what you're trying to accomplish. In general, I avoid having the view model know anything about the view. Both view and view model can be aware of the model. In certain cases, you'll want to make use of Ninject as a service manager in order to inject a view into the view model (without forcing the view model to depend on the view).


An entirely different approach would be to avoid a log in window altogether and display a login method in the main window. You'll still need some Model object to tell you when to show the login prompt, but you won't have to worry about juggling windows. Honestly, I'd probably go that route. WPF provides us with a lot of interesting and sexy ways to accomplish that task.

Ed Gonzalez
A: 

The Application object is the root of any WPF project. You are correct that you can handle the App_Startup event - depending on what you need to do at startup, of course.

Depending on whether you need a more complex navigation framework or the application will be forever limited to the scenario you described, you can go a multitude of ways from there.

What I'm doing in the applications I work on is I create a Navigator object that handles navigation both between different windows and inside windows, then I simply call Navigator.Navigate(new MyViewModel(), NavMode.ReplaceWindow); which closes the previous 'main' window (if any is open) and displays a new one, setting the contents to the instance of my ViewModel. The ViewModel is then displayed using the correct templates. I can also use NavMode.ReplaceUserControl which replaces the contents of the current 'main' window, or NavMode.OpenModalWindow which displays a modal dialog. My ShutdownMode is set to OnLastWindowClose, since I can always call App.Shutdown() if I want to close regardless of the open windows.

Of course, when you replace windows you need to make sure to instantiate (not show, just instantiate) the new window before closing the old one, to avoid application shutdown because you have no more windows.

You could do something similar, but it's just an idea and it's tailored specifically for my requirements.

Alex Paven