I'm learning some C# and in the tutorials, they usually put most of the code on the button clicks for the sake of teaching. For example, if they were going to show a streamreader, they would do:
StreamReader sr = new StreamReader();
..inside the button's click function.
Is this a bad programming habit? From javascript, I remember reading a warning on some code I wrote that said something about creating a function inside a timeout event. Should all variables and objects be declared outside of the button click function?
I'm learning some C# and in the tutorials, they usually put most of the code on the button clicks for the sake of teaching
The reason that putting code inside a click handler would be bad is that a click handler is specifically related to the UI, and the rest of your code might not be.
A stream reader reads from a stream. Code that processes a stream should be grouped with it. Code that handles the fact that you clicked on the UI has nothing to do with reading from a stream, so it should be separated.
Generally you should group your code so that parts of your code that are logically similar are together, and that parts of your code that deal with entirely different things are separated. This will give you "high cohesion". It is related to the Single Responsibility Principle.
Should all variables and objects be declared outside of the button click function?
Absolutely not. If it makes sense to create a specific object when handling a UI event, do so.
However as I mentioned before, if you're dealing with non-UI things inside a UI click handler you're doing too many things at once. Split out your streaming code into another method, another set of methods, or into another object. This will make it easier to read your code, it will make your code have a better chance of being reusable, and it will make it easier to edit your code.
UI logic and flow is notorious for being kludgy and requiring a lot of work-arounds and special handling. It is also the area of your app that you will get the most feedback on, so it will undergo the most change. Everyone will have an opinion on how your UI should work, including non-technical users. If you guard yourself against this by separating your UI logic from the logic in the rest of your app, then those changes will be much easier to make.
You can create instances within your handlers, this is common practice as everything is taking place on the UI thread within your handlers. In addition once the method completes that variable will go out of scope and get marked for garbage collection.
It all depends on how long you need the object to live, if you wont use it outside the button event then it probably should be there so it gets garbage-collected when the event is finished, if you do need to use your objects outside then using a field in your class should be fine.
No it is not a bad idea to create instances in event handlers, but if there is any code that you may want to call multiple places in your code, it is best to that part of code to a separate method instead of trying to simulate button click events
Related
In the baseform of a winform project the code for connecting to the database is moved from the load event to the show event.
In the show event there is a call to Update() before fetching data, this makes the form appear much faster which is more pleasant for the users.
But now I found code on some places like this for example :
FormRitDetail ritDetail = new FormRitDetail();
ritDetail.PrimaryKeyValue = ritID;
ritDetail.Show();
ritDetail.SendSaleEmail(cancelSale);
ritDetail.Close();
This worked perfect while the code for fetching data was in the load event, but now it gives an error which I have tracked down. In the SendSaleEmail method the data is not fetched yet.
The fetching happens in the Shown() event, but it seems that c# does the call to SendSaleEmail first, and than the call to Show().
How can I force c# to do the methods in the order as I write them ?
I can do a call to ritDetail.Update() after the ritDetail.Show() I know that, but I would like a general solution that does not involves writing additional code everywhere the show() method is called.
Is this possible ?
In the baseform of a winform project the code for connecting to the database is moved from the load event to the show event.
There is your real problem. You depend on an event to get executed to get into a valid object state. That's called temporal coupling. It's what makes you experience the current problem.
A general guideline is to never execute business logic within events. Instead create separate methods for that. Those methods can in turn be executed from the event handlers.
The other problem is that you need to load and show a form just so send a send email? At least I interpret your question as that the form will just open, execute and close. Move that code to a new class which just that responsibility.
So the answer to your question is:
Do not depend on UI events ensure that business data is loaded. It can be loaded directly but not yet populated into the form until it's ready.
Forms have a UI responsibility. They should not be responsible of business logic. Create separate classes.
Update
Regarding the actual problem, I just checked reference source for the Form class. The Show() method just changes the internal state (using SetWindowLongPtr WinApi function). Thus nothing is done until the message pump processes that message.
There is no guarantee that it's done before the next method call (i.e. SendSaleEmail).
hmm, I feel my OP title sounds wrong, but I am not sure how to put it...
I mean something like during the runtime, whenever a button button being click, dialog prompt up, any method being called etc. There will be some output that print out my StackTrace or something that indicates where I am in the code.
The reason being is, I just picked up a new project with very huge source code (62 projects in a solution), so pretty much I always have no idea whenever a Dialog or a View open, where the file is or a method is locate. So I want a good way to keep track on where I am, tell me which files or at least the method that calling it. Then I will know where to set a break point in VS.
But as I stated, the projects is pretty huge, so there is no way I can go to every Class and every method to add Debug.WriteLine("Method XXX being called").
So I wonder is there any way I can make a piece of code being called whenever any method being executed? i.e. Some event handler that will execute whenever method is being call? Or does Visual Studio have a functionality that can help me trace where I am in the code? (i.e Button being click, the last return line is XXXX)
Use a profiling tool.. Try "Ants"
A few things come to mind:
Apsect Oriented Programming
I've used this to weave in code at every method call to do extremely deep tracing. I happened to use Postsharp.
Intellitrace
This is a pretty handy tool from MS. It looks like you can do method call level logging.
My question is how programmers create, code, and organize subforms in general. By subforms, I mean those groups of controls that make up one UI experience. I'm looking for hints to help me better organize my form codes and to speed up the process of creating such forms. I swear to God, it takes way too long.
I've identified three broad groups of subform elements:
-Subforms have commands to do something.
-Subforms have data elements to carry out those commands.
-Subforms have states used to track things that aren't data.
The approach I use is to focus on what it takes to perform the commands which will determine which data elements are needed and how they should be validated.
Also, do programmers use check lists when creating forms?
p.s. I program as a hobby.
This is incredibly fuzzy. There is however a red flag though, you seem to be talking about UI as a starting point instead of the end result. That's a classic trap in winforms, the designer is rather good and makes it way too easy to endlessly tinker with form layouts. You forever keep adding and removing controls and event handlers as your ideas about how the program is supposed to work evolve.
This is backward and indeed a huge time sink. Effective design demands that you grab a piece of paper and focus on the structure of the program instead. The starting point is the model, the M in the MVC pattern. As you flesh out how the model should behave, it becomes obvious what kind of UI elements are necessary. And what commands should be available to the user.
The V emerges. Instead of jumping into the designer, sketch out what the view should look like. On paper. Make a rough draft of an organized way to present the data. And what operations are available to the user to alter them. Which selects the type of controls and the menus and buttons you'll need. Once that congeals, you can very quickly design the form and add the C. The event handlers that tie the UI to the model.
There's a very interesting tool available from Microsoft that helps you to avoid falling into this trap. I love the idea of it, it intentionally makes the UI design step imperfect. So you don't spend all that time pushing pixels around instead of focusing on the design of your program. It draws UI designs in a paper-and-pencil fashion, there are no straight lines. Incredibly effective not just for the programmer, also a "keep the customer focused and involved" fashion. So that the customer doesn't fall in the same trap either, nagging about a control being off by one pixel. It is called SketchFlow, link is here. It is otherwise the exact same analogue of paper and pencil, but with a 'runs on my machine' flourish.
Try CAB I'm not sure you should use it, but the pattern will help you understand how to write your gui layer in a good way.
I have some legacy code in C#, .Net 2.0 where someone dragged OpenFileDialog and SaveFileDialaog from the toolbox onto the form. This results in the open and save dialogs being instantiated when their parent dialog is created and remaining until the parent dialog is closed. The open/save forms are really only used in one place each for a support file that is not always opened/saved during the life of the parent dialog; this seems inefficient to me.
What I would do is:
using (OpenFileDialog openDlg = new OpenFileDialog() )
{
//initialize openDlg...
if (openDlg.ShowDialog() != DialogResult.OK)
{
//handle OK result
}
}
That way the OpenFileDialog will be disposed of when the using statement goes out of scope. Unless I am missing something the value of rapid disposal (and faster garbage collection) of a resource outweighs the small savings of not having to instantiate the Open/Save File dialogs when they are needed.
Even if the open/save dialogs were used every time their parent dialog is used, I don’t see any great value to having them around all the time. My question is am I missing something? Is there some greater efficiency to keeping the open/save dialogs around all the time?
I assume the answer will be the same for all the other standard dialogs: ColorDialog, FolderBrowserDialog and FontDialog.
Not necessary. These dialogs have a Dispose() method only because they inherit one from the Component class. They don't override the method since they don't actually have anything to dispose. All the system resources they use get released when the dialog closes. The Component.Dispose() implementation doesn't do any disposing either, it just makes sure that the component is removed from a IContainer collection.
This is otherwise an implementation detail of these dialog wrappers. Other components do normally have use for Dispose(), ToolTip being a good example. The auto-generated Dispose method for a form makes sure that this happens, check out the "components" field in the form's Designer.cs source code file. Which is why Component has a Dispose method that doesn't do anything important by default.
There's one teeny advantage to avoiding dropping the component on the form, it allows the .NET wrapper class for the dialog to be garbage collected. But the kilobyte or so that saves is a micro-optimization.
Take this at face value: if early disposing these class objects would have been important, Microsoft wouldn't have made them components.
I think the "on form" option is just supposed to be easier for a novice to implement, since the work is mostly in the editor instead of in code.
Good practice would be to do what your doing since you've stated that these dialogs don't need to sit around in memory very long, but if they were to be used many times, it's a good idea to leave it around and dispose of it properly when the application closes, simply depends on the situation.
Given the situation it sounds like your good going either way and I wouldn't lose much sleep over it, but regardless whether it does anything useful in it's dispose method, the way your using it is recommended, its just good practice.
The advantage is you can set up the dialog however you need (multiselect, initial directory, extensions) etc in the form designer.
Also the form designer makes it so easy to drag an OpenFileDialog onto your form that many developers just do it. Can't really blame them.
There's no significant advantage or disadvantage to either approach, I doubt you'll find any perceivable performance difference.
I generally create form-scope dialogs when I want to persist certain settings, such as filters, without having to set them each place I use the dialog. If a dialog is used only in one place, I use a using statement, as you have above.
I always wondered about this approach as well as I prefer the usage pattern in your snippet. The only possible reason I've ever been able to come up with is that by making them components, their properties can be configured in the designer.
Not a very compelling reason (IMHO).
I generally agree. But there could be a slight performance gain if the dialogs have a lot of 'default' property data. Think about a file open dialog with 50 file type filters.
I was thinking of centralizing this functionality by having a single method that gets passed an AppState argument and it deals with changing the properties of all GUI elements based on this argument. Every time the app changes its state (ready, busy, downloading so partially busy, etc), this function is called with the appropriate state (or perhaps it's a bit field or something) and it does its magic.
If I scatter changing the state of GUI elements all over the place, then it becomes very easy to forget that when the app is in some state, this other widget over there needs to be disabled too, etc.
Any other ways to deal with this sort of thing?
Emrah,
Your idea is good. You need to limit the state structure and this is the only way to ensure reliable UI. On the other hand do not follow the "one function" idea to strictly. Rather continuously follow its direction, by creating a function and then do progressively refactoring all attributes to a single "setter" function. You need to remember about a few things on your way:
Use only one-way communication. Do not read the state from controls since this is the source of all evil. First limit the number of property reads and then the number of property writes.
You need to incorporate some caching methodology. Ensure that caching does not inject property reading into main code.
Leave dialog boxes alone, just ensure that all dialog box communication is done during opening and closing and not in between (as much as you can).
Implement wrappers on most commonly used controls to ensure strict communication framework. Do not create any global control framework.
Do not use this ideas unless your UI is really complex. In such case using regular WinForms or JavaScript events will lead you to much smaller code.
The less code the better. Do not refactor unless you loose lines.
Good luck!
Yes, this is the most time consuming part of the GUI work, to make a user friendly application. Disable this, enable that, hide this, show that. To make sure all controls has right states when inserting/updateing/deleteing/selecting/deselecting things.
I think thats where you tell a good programmer from a bad programmer. A bad programmer has an active "Save"-button when there is nothing changed to save, a good programmer enables the "save"-button only when there are things to save (just one example of many).
I like the idea of a UIControlstate-handler for this purpose.
Me.UIControlStates=UIControlstates.EditMode or something like that.
If having such object it could raise events when the state changes and there we put the code.
Sub UIControlStates_StateChanged(sender as object, e as UIControlStateArgs)
if e.Oldstate=UIControlStates.Edit and e.NewState=UIControlStates.Normal then
rem Edit was aborted, reset fields
ResetFields()
end if
select case e.NewState
case UIControlStates.Edit
Rem enalbe/disable/hide/show, whatever
Case UIControlStates.Normal
Rem enalbe/disable/hide/show, whatever
Case UIControlStates.Busy
Rem enalbe/disable/hide/show, whatever
Case Else
Rem enalbe/disable/hide/show, whatever
end select
end sub
#Stefan:
I think we are thinking along the same lines, i.e. a single piece of code that gets to modify all the widget states and everyone else has to call into it to make such changes. Except, I was picturing a direct method call while you are picturing raising/capturing events. Is there an advantage to using events vs just a simple method call?