I'm creating a web form, where in there are around 12-15 Input Fields...
You can have a look at the screen here http://img9.imageshack.us/img9/2951/image001um.jpg and here http://www.freeimagehosting.net/uploads/f9f4491598.jpg
The request is such that depending on the data the user selects in the Gridview and the DropDown list, the appropriate Textboxes and CheckBoxes needs to be displayed.
Some times the conditions are very direct, like when the DDL value is "ABC", get only paid amount from the user.
Sometime they are so complex like... IF DDL is "DEF" and Selected GPMS value is between 1000-2000, calculate the values of allowed, paid etc (using some formula) and the focus should be directed to Page No Field, leaving the other fields open incase user wants to edit... There are around 10-15 conditions like this.
As this was done through agile, conditions were being added as and when, and wherever it feels appropriate (DDL on change Event, GridView on selecting change event etc... etc..) After completion, now I see the code has become a big chuck, is growing unmanageably...
Now, I'm planning to clear this... From you experience, what you think is the best way to handle this. There is a possibility to add more conditions like this in future...
Please let me know, incase you need more information. I'm currently developing this app in C# .Net WindowsForms
Edit: Currently there are only three items (The Datagrid, the DDL, the OverrideAmt CheckBox) that change the way other fields behave...
Almost all of the conditions will fall between the two situations I mentioned...
Mostly they belong to "Enabling/Disabling".. "Setting of Values"... and "Changing Focus"
or any combination of these.
Minimal overhead
Write a single-procedure that contains all the evaluation logic.
i.e. evaluate all the individual states and show/hide the appropriate controls from within the procedure.
Now call this procedure whenever there is any change event
that requires you to re-evaluate whether to show/hide any controls.
Do NOT show/hide any controls from outside this procedure.
Any additional validation-checks in future can always be easily incorporated
by adding the additional checks inside this procedure.
To improve upon the performance of this procedure:
[1] Add a parameter (int/string) to the procedure.
[2] Pass a different value in this parameter when calling from different events of different objects.
[3] In the procedure, from on the value of the parameter, you can determine what object(& what event) has triggered this re-evaluation.
Thus You can evaluate only those conditions that could possibly depend on this particular change in this particular object. This way the re-evaluation overhead is reduced to the bare-minimum.
Related
I am making a basic ticketing system in C# with basic coding experience. Most of my experience is in SQL.
I have the database and tables. I have stored procedures to create and amend tickets.
I am stuck (this is probably very basic) because:
On my EDIT ticket page, I populate various text boxes and drop downs from my existing data via inline SQL.
On my page, I can edit all the fields and dropdowns with new values. (i.e. change a ticket priority from when it was first logged)
I have a button, that calls my "update" stored procedure, however it updates only the NEW fields I have, any amendments to the existing fields are overwritten by the original values before submitting.
The original values are called on pageload, so I think the button reloads the page before submitting. I want it to submit all the values that are on the screen.
I think this must be something obvious, remember I am a novice so I may have missed something simple.
If what you're saying is you load values from the DB into the form controls in the PageLoad event handler, then yes, you're probably overwriting the changed values. To keep things as simple as possible for you, wrap the original values loading code in the following:
if( !IsPostBack )
{
// load initial form values here from DB
}
I'd suggest you read about the ASP.NET page lifecycle: http://msdn.microsoft.com/en-us/library/ms178472(v=vs.90).aspx
In my application, different controls are only used dependent of the values of properties from a particular object. The forms constructor accept this object as a parameter.
The form has always some basic functionality, no matter what properties are set of the particular object.
Now I have something like this:
if(myObject.SomeProperty)
{
myControl.Visible = true;
myOtherControl.Visible = false;
// and so on
}
At this time, the controls that are dependant of SomeProperty are buttons and tab items. However, I can imagine that in the future other controls are added to the form and are also dependant of SomeProperty.
As you might guess, I want to set this up the right way. But I don't know exactly how. How would you implement this?
There are multiple ways I can think of solving this, depending on your situation you could select the best suited to you.
1. Databinding is one elegant solution when managing the state (visibilit or other properties) of multiple control's depend on a different object. Additional details in this question
2. You could write different functions if the combination of the states is only limited to couple of cases to at most 4-5 cases. That ways you can still reason about the methods which set the state depending on the object you are depending on. Ex: Basic_Editing, Advaced_Editing, Custom_Editiong etc.
3. If the number of cases are limited you could create multiple forms (User controls) and load them on demand based on the state of the dependent property (or object you are talking about).
Just having a bunch of if else's makes your code harder to maintain, or comprehend, logically group the states so that 1. You could reason about it later, 2.Someone else understands the reason/logic 3.When there is a change required it can be localized to one of these modular methods (techniques) reducing the time to fix, and test.
I would do it like this in form constructor:
myControl.Visible = myObject.SomeProperty && !myObject.SomeOtherProperty;
myOtherControl.Visible = !myObject.SomeProperty;
....
Is it the less code and its rapidly changing.
OR
You can create separate functions that will generate controls dynamically at runtime for each form view based on object properties.
First i can see you are setting visibility on/off it means you have already controls on the form every time.. , so that not a good practice, instead create controls only when needed.
As for your scenario you can have an function like Initialize() which contains all the code for checking if showing a particular control should be shown or not and then create it and add it to Forms control collection. If any new control come to be added later you have one function to update.
A more precise answer can be given if you can provide more detail to you scenario
(C#/SQL/Approach-question)
This has to be one of the hardest nuts I've ever had to crack. So I sincerely hope one of you smart people out there have tried to solve this before! :)
I have a much of categories (A,B,C) with pictures.
For each picture I need to ascribe some information, based on some controls that have either no- or predefined options. For instance in category A I have a textbox where you can enter anything you want, and a dropdownbox where you can choose between 3 options.
Now, for each category I would like to be able to design (decide) which controls (text, select, checkbox, radio, etc.) I want to ascribe to a category, and I want also to be able to decide what values apply to that control. Let's say I have a select-control, and I want to be able to decide if multiple select are allowed, and which values are available.
So the end product would be:
I can administrate what categories have which controls in them, and which options are available (i.e. single or multiple select) as well as which values are ascribed or allowed.
I need to be able to store this information in a persistable fashion.
I need to be able to "easily" parse the return-data from the page where the controls are rendered.
I realize this is a complicated question, and I will be happy to answer any questions you might have to help clarify the problem.
Thank you in advance!
You could separate the render part (dynamically generated) apart from what to render(based on categories).
Assuming you will use winform controls.. you could have a config file or a simple SQL table that follows schema below:
Table_Category (CategoryName, nickNameOfControl, NotNull, OtherAttributes)
Table_Control (nickNameOfControl, ControlType, Values)
Based on your actual table design, you will be able to CRUD on the tables design time for administration, your render part of the program can read the ControlType information (TextBox, ComboBox etc) and dynamically generate the controls at run time.
Hope this helps.
I have a form with several components, like TextBox and ComboBox, and I need to know when click in the out button if there was any changes in the form. Is there a way to do this?
You could create a generic change event handler which sets a flag on change, and then assign all the controls' Change events to it.
This could probably be done pretty easily by looping through all of your controls onload.
You could loop through all controls but this would have to be recursive because a control can contain controls, e.g. (no null checks for brevity):
private void IterateOverControls( Control parent )
{
ProcessControl( parent );
foreach( Control control in parent.Controls )
IterateOverControls( control );
}
In ProcessControl you could hook up event handlers to handle OnEnter (to store the state) and OnLeave (to check the current state against the stored state). You'd need to unhook all the event handlers when disposing. Also, the code to store check the state would have to change for different control types, e.g. TextBox would be the Text property, but a radio button would be an index, etc. Obviously this becomes simpler if you can compare form state to your underlying data store state, in which case you can just make the comparison on each OnLeave event.
One thing also to consider is do you need to track real changes? For example, I have 2 radio buttons: A and B. I check B (a change), so the out button or whatever has its Enabled property changes. I then click on A (i.e. back to my original state). Do you need to revert the button at that point?
This is why you should look towards a model view controller approach :)
The easiest way to do this would be to simply use a variable on the form named something like "IsChanged." Set it false when the form is initially displayed, and set it true if they make any changes.
Alternately, you could record the values of everything when the form is displayed, and when they finish, check the current values against the old ones to see if anything changed.
If this is already nearly finished, and you need something quick it's probably going to be easier to just always assume that something has changed, then in your update logic afterwards (whatever it's doing) don't update stuff that is still the same.
As someone else mentioned, it's very possible for someone to change something, then change it back. What would you want to do in that case? You won't be able to maintain a proper dirty state of the form without a fair bit of additional work.. this is something that you need to plan for before you start, really.
Currently, I'm in the process of making a custom solution for invoicing. I have created multiple ways for customers to create their template (HTML, Word, LaTex) and get invoices according to their template. However, these invoices are party manually generated.
So, the process is:
Request to create a new invoice
An preliminary invoice is created
The user gets a chance to make changes (i.e. add, remove, change rows)
Create a pdf
Just to be clear, the preliminary invoice does not need to be formatted as the template is, but you should be able to add/remove/change rows and for every cell, indicate whether the value should be visible in the final result.
My problem is that i cannot find a suitable way to display the preliminary invoices. I tried a datagrid (default, telerik, devexpress), but it's too messy. Besides a datagrid, i have no idea what i can use.
What controls can i use best to have a nice and usable UI.
Please don't be like this:
alt text http://bitsandpieces.us/wp-content/uploads/2008/03/imagesapple-20google-20and-20you.png
A typical UI paradigm for this kind of thing is to view it as two separate problems: giving the user a way of viewing the elements that he can modify, and giving him the ability to modify any specific element. You use a list control (ListBox, ListView, maybe TreeView if the elements are organized hierarchically or need to be grouped into categories) to present the elements, and then when the user selects an element the program presents a tabular presentation of field names and editable value controls.
Basically, you're dividing the program's functionality into two categories: stuff that the user wants to do to rows (add, remove, re-order, select) and stuff that the user wants to do to the selected row's elements.
You can mush these two sets of functionality into one if you use a DataGridView, but as you've seen that gets pretty ugly if there's any complexity to the elements you're editing.
Two possible approaches to this: the property-sheet paradigm (select object, right-click, select "Properties", edit values in a modal dialog), or a paradigm where the window's split into two panels, with one being the rows and the other being the details of the currently selected row. There are lots of others.
What is your platform? Winforms? WPF?
What exactly did you dislike about using a datagrid for this? Part of the problem is that whether you like it or not, you're going to be coding a datagrid - you essentially described features of one. If at all possible try to use someone else's datagrid because it will save you a lot of work. Typically, 3rd party datagrids should be fairly customizable, and you should be able to make it look however you want - and take advantage of the built in sorting, editing, grouping, etc. Creating a datagrid-like control from scratch isn't easy and should be avoided if possible.
You don't have to have a plain giant datagrid - you can crate a custom control that displays the invoice formatted however you like, with a live datagrid appearing only where the invoice shows tabular data, formatted to appear as an integral part of the invoice itself.
I'm doing something similar, where the client can edit or even remove the line items for the invoice prior to sending it to the client.
The current app they run their business on is a WebForms Intranet application, so this is an extension to that. So they can add/remove/edit rows fairly easily.
But Egor is right. You're essentially talking about a datagrid no matter what you do. I take it you want something 'cleaner' and more intuitive?
Simplicity is difficult.
I would take a look at what is already out there, especially for invoices, and see how they are doing it.
Not sure how big your company is, but it never hurts to take advantage of the large company applications and user interfaces, the pour thousands/millions of dollars into user interface design and testing.
I would take a look at any of the following (most offer a free trial, or just try searching for screenshots):
www.freshbooks.com
www.invoicera.com
www.getcashboard.com
www.simplifythis.com
Just some ideas ... hope this helps!