I'm trying to modify a C# WinForms application that uses multiple forms. At startup, a login window will be shown. If the user logs in with a correct user name and password combo a form with three different tabs will be shown as a sort of administrators view. If no password or user name is supplied, a much simplified GUI will be shown. It will basically consist of two buttons that in turn shows these two forms depending on which button is pressed:
Button 1: Give the user access to a form consisting of a number of textboxes where the user can input information that will be saved to a database. Once the DB-operation has been executed successfully, the first form with the two buttons will be displayed again.
Button 2: A form is shown where the user can input a code that will be written to DB. Once the DB operation is concluded, the user will automatically be taken back to the original form with the two buttons.
Both forms will also have a back button to take the user back to the first form. I have a lot of logic in place, but I am unsure of how to best handle all the forms involved. Where should I instantiate the first (login) form? Once the login validation is done there are two possible ways to go. Either show the tabbed admin form (if user name and password is correct) or the simplified user form with two large buttons. It should also be possible to logout from the admin form so that the simplified GUI is shown instead.
I hope I am making sense here. I just need a good way to handle all the forms and navigation between them. Currently, there aren't really any need for transporting data between them, but it might be an issue in the future so a solution that takes this into account would be excellent.
I'm thinking that what is needed is really a class that handles the displaying and disposing of the forms right from the start, but I'm not quite sure where I should put the instantiation of this handling class.
I just did something similar. I had a set of forms to manage as "pages" as the spec called them. I also had strict page flow that was a bit more complicated than yours. I'll talk you through that.
I designed each "page" of interaction as a UserControl and created an "OuterForm" and a "Controller". The controller had a Navigate(string pageName) method and the outer form contained a panel and had a Display(Control page) method which cleared the children on a panel and added the replacement.
I used Spring.NET to configure the controller and the form and used setter injection to create a two way link between the two. That meant my main method could ask Spring for the form and just display it using Application.Run(form);
I created a convenience method to access the controller from event handlers and would do e.g. Controller.Instance.Navigate(chosenPage); The controller also used Spring.NET to load the correct UserControl for chosenPage and then called on the main form to Display() the instance it loaded. There as no Spring.NET code in any user control, and no new keywords either ;-)
The advantage for me in using Spring.NET is that I had one form class that just monitored some business logic and displayed a progress indication. I was able to implement that once and configure many instances of that form injected with different business logic that it would monitor. Also, I needed to stub out interfaces to domain specific pieces of hardware and web services. Eventually I moved page flow into the configuration as well.
Form management can be a tricky issue. There are some different ways to go:
Just have the forms float around on the screen. Let some static class hold references to the different forms and expose methods to activate them.
Implement the forms as UserControls instead, put them onto the same form, and show and hide the controls as appropriate (this can also be achieved by loading the forms, stripping form borders and such and setting their parent to a panel or something similar; this will almost make them behave like user controls, but only almost)
There are many other methods, of course ;o)
When it comes to managing the login form, I would do that in the Main method; show the login form, check the credentials and then instantiate the UI you want to show and pass that to the Application.Run method.
Have you considered using a Composite UI framework? In your case, you could use WinForms with CAB.
One of the big advantages is the support for role based authentication. An authenticated session could match one role, a non-authenticated session could match another role. Thus you can display different screens depending on the role of the user.
Another advantage is the answer to the problem of who is responsible for instantiating screens. This is managed by the controller, and actions on the screens (eg button click) can send events to this controller.
Last but not least, there are some good samples available and there is definately support for more advanced scenarios.
Related
We are developing a winform application that does data intensive work. Our queries (BI tasks) can take up to a minute to conclude. We have four important processes, and we want to show their state in one single window. With that in mind, we have developed four user controls, each one shown in our main form. There are three researchers working on their own user controls, and we are integrating them on the main application.
The problem is, when one user control is refreshing, the application will freeze. What should my approach be to make the user controls refresh asynchronously? Is there a solution that I can use, in order to create a Base class or interface that will force the developers of the other controls follow the same method?
I've created a win form application which consist of a single form. We have 8 tabs to access the modules of application.
The problem is we are a team of 4 who works on this project. But since it is a single form application, only one person can use the file at a time. Is there anyother way to build application with more than one file?
Please provide some solution.
Firstly, you should probably have a separate UserControl per tab. That will give you 8 files (at least) since you have 8 tabs.
Secondly, you should be using a Model-View-Controller style architecture for Windows Forms applications. That will give you at least one controller, but likely you will have one controller per UserControl (i.e. per tab). You might even have an overall controller that manages the per-tab controllers.
You might only have one data model for the entire app, or you might have one data model per UserControl (tab).
If you did all that, you'd have a few more source files.
However, it's actually difficult to say without knowing anything about your app.
Try using user controls to make each tab modular.
Figure out what are the parameters that each tab accepts and that it exposes and then create user controls that have that behavior.
Here are couple resources to get you started
http://msdn.microsoft.com/en-us/library/aa302342.aspx
User Control vs. Windows Form
User Controls in Windows Forms - Anything similar to ASP.NET User Controls?
Even if this is a giant ball of wax, your source control tools are shoddy and breaking it up into separate classes is hard to do, you can still take advantage of a Form class being a partial class. Which means that you can spread the code over any number of source code files, not just the two files that the designer creates. So a logical organization is to move code that belongs to a particular tab in its own partial class with the same form class name and its own source code file. Some cut+paste required however when you add event handlers with the designer.
Have you considered using MDI?
MSDN Working with MDI...
Examples are in VB.Net but I'm sure it will be easy to use C# if you really want to - I'm not sure why, but... :)
I am creating a windows form application in C# and I have two forms. The main form where the user is going to be working with a graph and another form that contains: series appearance options, axes options, label options, etc...
This form appears when the "Tool" button is pressed. From there I intend to let the user modify their graph as they wish. My question is-
Is it faster/better to populate the second form when the first form loads or initializes, or should it just do that when the "Tool" button is pressed.
This question is about a difference between eager loading (load data as soon as possible) and lazy loading (load data when it is necessary). I think the decision here should come down to user experience. If the data takes a little while to load and your users will be accessing the properties window frequently then I would suggest eager loading. If on the other hand the loading is quick or this is a feature that is going to be infrequent then I would suggest lazy loading. So, you need to figure out what your users expect. But, if the data for the screen loads quickly then it hardly matters what you load when.
I would also suggest that you rethink your properties window, especially if it is going to be used frequently. The paradigm for this kind of user interface has been to embed a PropertyGrid into the same application window where the bulk of the work is done. Think about Visual Studio for many, many examples and just about any IDE-style application. They do not tend to have "floating" properties windows. The paradigm is that you show the properties of whatever object is currently selected in the IDE to allow quick and easy modification. The separate Tools | Options paradigm is more for application-level settings that are modified much less frequently and are tied to the app at large rather than particular objects that the application manages. Again, Visual Studio is a good example.
In my opinion, it would be better to make a new instance of the second form when you click on the appropriate button. I would think that you should only allocate the memory for the form when you need it.
However, if your forms are quick to load, it should not matter from a user standpoint, as long as you hide the second form until the button is clicked.
Creating several forms at startup isn't very scalable. When you have 20-30 forms it will takes ages to load! Create them as and when they're needed.
// button event in your first form (Form1)
private void firstButton_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.ShowDialog(); // Shows Form2
}
Should be used, since you might not need the button at all.
I have a winforms tab control which has several tab pages. Within each tab page controls (textboxes, radio buttons, etc...) are group into groupboxes. These group boxes are arranged from top to bottom but in some occassions some groupboxes needs to be visible and other ones to be hidden. Also control within each group box sometimes (depending on the scenario) needs to be visible and sometimes hidden. So I would like to know if someone knows a good approach to do this, maybe some kind of pattern if any. Also it would be good to implement a generic solution to do this. Could any expert in GUI guide me in the right direction to do this?
Using C# and dot NET Framework 4.0, WinForms. This is a desktop application, not Web-based.
You can define the scenarios in a class then add another class that will manage the layout by reading the scenario and laying the elements based on the scenario. I have not provided details because it varies on how specific you want to be and what behavior you want to achieve. It is better to put the Widgets inside a User Control and let that user control communicate with the layout manager.You can use the Mediator pattern or variation of it to coordinate between the widgets. Hope this helps.
I usually try to group related controls into UserControls (even if this means doubling up on some controls) and adding them to or removing them from the form as needed. An example of this could be payment methods - when the user selects a specific payment method (Credit Card, Cash, Cheque, etc) a UserControl with the correct elements is displayed within a panel on the form.
A good pattern to use when managing this sort of set up is Model-View-Presenter, in the example, all the UserControls would probably implement an IPaymentMethod view interface and provide a way to update the corresponding models.
I am going to start a website, where We want to implement MVP pattern.
One of our page is broken into small user controls so they are used to
edit or display information. But later on we save the whole information
from the main page. Also during the load time, the information is sent
from the main page to the controls. If I design a separate Presenter
for each user control and write logic in that to capture information, there will be many calls to database, whereas if i write that logic in the main presenter and pass data to the user controls, it will just one call. how should it be designed.
Let me explain it.
I have a webform where I capture details like Car make, model, milage, client detail
like name, contact phone number etc. all the controls can be put into one form,
but instead, I created separate controls for each information, like one control for car information, other for customer information. But later on, I want save the whole information from the main page not from the controls. So how will i achieve it using MVP pattern. Should I create separate presenter for each control, then how will I pass information from a user control to the webform, when hit the save button.
Your help will be appritiated.
Regards
Parminder
You should use a Unit of Work design pattern for saving information, where each child control will add queries to save and your main control will SubmitChanges.