Winforms MVP-VM Pattern - How to limit functionality when logged out - c#

Background
I'm creating a windows forms application that implements the MVP-VM pattern. This post explains the overall approach I'm taking:
http://aviadezra.blogspot.ca/2009/08/mvp-mvvm-winforms-data-binding.html
My application has a main window that opens on application start-up. The main contents of the application are hidden until the user logs in, after which the user controls which expose application functionality are revealed.
The main window has multiple presenters, each one representing a different set of logically grouped functionality. When the application starts, only the presenter that creates the login dialog is populated. Then, once the user logs in, the remaining presenters are created. I feel this is a good way to prevent users from somehow accessing functionality until they are logged in.
Question
When a user logs out, I'm having trouble deciding what needs to be done. I don't want to re-create the main window, but the state of the main window at login is I think what I'm trying to achieve (only the one presenter initialized). When someone logs out, should I dispose all presenters except for the one that creates the login screen? How do I do that? I don't imagine just setting the presenters in the main form to null would work, eh?

Related

Raising an Event from the Shell in Prism. Is There a Way to Use a Shared Service? Or Just Use PubSubEvent?

I'm using Unity for Dependency injection under Prism and have a situation where one of my modules is to display a screen saver of sorts when the user is running a test and no input has been received. (The region holding the view for this module displays in front of all other regions.) The idea being if the user goes to the other side of the room while the test is running, they can see a summary of relevant test information. When they interact with the application again, the screen saver will exit and return them to the main display.
Since the Shell is what captures user input, I need to alert the screen saver module to hide the view when the user interacts with the computer.
The screen saver module itself implements a shared service interface in the ViewModel that consists of an Enable() method and a Disable() method. The screen saver is only enabled when a test is running. The modules that run these tests will call Enable/Disable as needed. The ViewModel contains an internal timer that when the Screen Saver is enabled, will trigger the display of the View upon expiration. If the user interacts, the timer will reset (and the View is hidden).
I'd like to keep my application from having a large amount of PubSubEvents when its not necessary to have one. In this case, when the user interacts, I'd like to be able to add a method to the Screen Saver service that the Shell can use to signal the user interaction. However, I don't see how that is possible without a PubSubEvent, since the shell is created before the Screen Saver module, unless I want to use a ServiceLocator or by adding a reference to the Screen Saver project in my Shell, both of which I think are worse options than using the PubSubEvent. Even if I separate the services into their own separate module, and reference that from the Shell/Boostrapper (registering via ConfigureContainer()), that module will still need to somehow be able to communicate to the ViewModel to reset the timer/hide the view.
Am I just overthinking this? Is there some other way I can do this? Or is my initial idea of PubSubEvent the best way. I'm rather new to Prism, so I'm still getting a handle on best practices.
I cannot see anything wrong with using the EventAggregator, but you can, of course, use a specialized service that does basically the same thing, just only for enabling/disabling the screen saver. Just register that service as a singleton and have it injected wherever needed.
To make things a bit nicer, seperate the active (e.g. EnableScreenSaver() and DisableScreenSaver()) and passive (e.g. IsScreenSaverEnabled property and ScreenSaverStateChanged event) members into two different interfaces, implemented by the same service. This way you get a little bit of advantage over the EventAggregator - events cannot be publish-only or subscribe-only, whoever knows the event can always publish and subscribe. But you can make the active interface known only to the parts of your app that want to control the screen saver, whereas the passive interface can be only known the parts that have a screen saver that needs to be controlled...

Who can see my Singleton?

I have an n-tier application. The front-end is an MVC site (if that makes a difference). The MVC site, the business logic and the DAL all have access to a specific shared DLL in which is defined a Singleton class.
This all works, as if I assigned a value of "foo" to the Singleton's property Bar in the DAL, the front-end will see "foo" when it accesses Bar.
The question is, what else can see the Singleton? If another users logs in to my MVC application and a page that page sets the Bar property to "Fred". What will my first user see when he accesses Bar.
Is a Singleton truly the only instance of that class? Or is it the only instance of that class for a given user?
What about if the first user opens another window in the browser in the same app? If he causes Bar to be changed in one window, is it changed in the other?
The question is, what else can see the Singleton? If another users
logs in to my MVC application and a page that page sets the Bar
property to "Fred". What will my first user see when he accesses Bar.
All the users see the last value. ("Fred" in your example)
Is a Singleton truly the only instance of that class? Or is it the
only instance of that class for a given user?
It's the only instance of the class across a thread. If your web application runs in multiple worker threads, you will have multiple instances.
What about if the first user opens another window in the browser in
the same app? If he causes Bar to be changed in one window, is it
changed in the other?
when you're talking about "web application", the term "window" is not so good. each window is created by a request. and each request can change your singleton object value.

Are actions on active window through c# possible?

I want to write some code, that can automatically do actions on active windows.
For example, if i want to press the ignore button once the window that pops if I insert a new DOK.
i thought of a code that once a specific (known) window pops, it presses a few TABs, and presses Enter.
Can I implement such a code? preferrable in C#.
I thought of several answers to your question because it isn't clear what you are asking. One of these topics might be an area for research:
If you want to press keys for the active window in an application other than the one you are running, you might read about elevated privileges, interprocess communication, and accessing the keyboard with Windows function calls. You can not normally do anything to other applications other than to cause Windows to send it various messages. Thought: how will you indicate when the press the keys if your application is not the active window?
If the active window is one within your application, then you will be better off in the long run by finding a solution that fits C#'s object-oriented model. If you want certain code to be run at times for certain windows (when one is active), you can share code by putting it into a common superclass and having your window classes inherit it. Looking at it this way will be instructive, but you may have to find a somewhat different solution, since it sounds like your window should be inheriting Window's Window class (you can only have one parent class in C#). You could look up "class inheritance" and perhaps "interfaces."
Another solution that isn't so object-oriented for sharing code is to put it into a static function and call this function as needed in the code of your active windows. But ideally, it is code in the active window class that should be manipulating the window. You can put it into a function and then call the function from anywhere in the application that has the "this" reference for the active window.

How to get and handle form changes in a different form that is accessible from Application.OpenForms?

I'm currently using a delegate to poll the current active control from the currently focused external form every few milliseconds, which works badly.
The title of the question is somewhat confusing, as this does not actually have anything to do with Application.OpenForms. That property just exposes a collection of all the currently open forms. If a new form is opened that had not previously been opened, it will be added to the collection. But the operating system allows only one active window at a time on the desktop, so what you really want is to get notified when the active window changes. Polling will work for this, but it isn't a good solution.
You will either need to install a global hook (WH_CBT is likely the one you want), or take advantage of the WinEvents infrastructure (via the SetWinEventHook function) intended for accessibility tools. Both of these will provide you with a notification when the active window changes. Of course, their scope won't be limited to the application that you are testing. You'll get notification when the active window on the desktop changes to any other window. It will be up to you to filter that down to the application you care about.
I don't have time at the moment to translate any of the required code to C#/.NET, but you can probably find it somewhere online, once you know what to search for. Additionally, WinEvents is already wrapped for you in the System.Windows.Automation namespace.

How to close an unknown childwindow?

I have some session management code in a silverlight application. As part of that session management, I automatically log the user out if they are idle too long. When the user logs in again, any ChildWindow that was open in the previous session will still be open. All other session data is reset though, so the ChildWindow is effectively orphaned. Any attempt to work with it will throw errors. How can I kill any ChildWindows when I do the logout?
How can I find any child window that may exist, and kill it so the logout can work correctly? My first thought is to start looking along the lines of this.GetVisualDescendants().OfType<ChildWindow>(); from the shell. However, in testing, this was empty even when I had a childwindow open.
The app is a silvelight C# app using Prism & MEF.
Edit - adding more detail / another way to phrase the question:
So the program flow would be something like:
User Logs in to the silverlight Appliction.
User navigates around in the app and opens a ChildWindow.
User abandons their computer to refill coffee and ends up in a 20 minute conversation.
User's Silverlight "session" times out. All user-specific information is discarded and the login window (another ChildWindow) is shown.
User returns to computer and sees a login prompt, logs in.
User sees the ChildWindow they opened just before heading out for coffee.
User tries to click on something in the ChildWindow and gets an error, since all the context that the ChildWindow had was thrown away when their "session" ended.
I'd like to add to my session timeout code (or even post-login code), something that finds any open ChildWindow and closes it, in order to prevent this situation that leads to the error.
So, I apparently stumped everyone, or more likely didn't make my question interesting enough.
I did find a way to solve this though. I created a custom base class for all child windows in the application. In that base class, the ChildWindows register/unregister (in Loaded/Unloaded event handlers) themselves from a static list that can be used to get a reference to any active ChildWindows.

Categories

Resources