I have a property that references a service layer object and I need it every time I use a form.
What is the best pratice: initialize a property in the constructor or in the form's load event?
If the validity of the state of the form is dependent upon the property being set, then set the property in the constructor. You always want your objects to be in a valid state after they're constructed.
Yeah, but be careful what you do in the constructor of a form, as the visual designer will run this when you open up the form to edit.
If you put anything here that relies on other stuff being set up at run time, it is likely to cause an error and you wont be able to edit the form layout.
I would say put it in the Form Load for this reason.
In the constructor. Very often you new up a form, and need to set some properties, or do other kind of set up before you actually display the form. In those cases, you'll want all your instance variables to be set up even before the Form actually loads up.
Constructor should be responsible for initialization, unless you have specific need or dependency to initialize your variable on Form Load, such as initializing it to something that is dependent on something else.
You should initialize properties in the constructor. The constructor is obviously called only once per form instance. The load event handler will be called every time a form is shown. Also, if you did initialization work, such as fill a combo box, in the load event handler, you'd have to write some pretty hacky code to preselect a value in that combo box before showing a form. That's just one example though. Hope that helps.
Related
I'm creating a control, and adding a property (control's look depends on it). How can I set this property:
I can't set the property in form constructor immediatly after InitializeComponent() call. In this case user will see two frames of form initialization: the first — after InitializeComponent(), and the second — after property setting, that invoke control's redrawing. Bad.
Also, I can't mark my propperty with BrowsableAttribute, cause a type of the property, is my own class, that can't be configurated in «properties window». Аlso bad.
So, how could I inicialize the property between form1.SuspendLayout() and form1.ResumeLayout(false)?
Ideally, I would like to have possibility to write a code directly in a respective field of «properties window». For example I would write new MyClass(param1, param2), if type of the property is MyClass.
Don't force the controll to redraw on property change. It's not necessary when you initialize the control and when a user change the property it will be redrawn in the next paint event. If needed the user can call .Refresh() on your control after setting the property to force the redraw manually.
I have a requirement which adds html/aspx components from code behind. The components can be either Check box or Radio button and options for them comes from the Database.
So what is the best approach to do this. Is user control helps here?
You should generally determine and add such controls via the page OnInit overload or Page_Init event, and be sure you do it on all requests, including postbacks.
Define local variables to hold the objects you may create (it could be a List<> if you don't know how many will exist ahead of time), and instantiate them as any other object, set their properties, and then add them to the Controls collection of the container item they should be in; By default, they will be added to the end of the container, but you can Insert them instead of Add if you like.
Assuming you re-create them like this every time, and do it during Init, you can then access them - including viewstate, if applicable - from the Load event/overload.
I have an mdi child form as a dockable content in my application and I want to disable/enable a listbox in it from the parent form depending on a certain event. I thought this would be simple as:
_child.listBox1.Enabled = false;
But it doesn't seem to disable it. _child is an object reference of the mdi child form btw. Why does it not work and how can I fix this?
_child probably refers to a different instance of the child form.
Make sure that _child refers to the same instance that you called Show() on.
Can't you create a function on your MDI child which would disable the listbox, you could call from the MDI parent?
I guess that here listBox1 is private (which is the default if you have constructed your form using VS designer)
Although it works, exposing the control of a form as a public property is considered a bad design practice.
Suppose that at some point in the future, you will have to change the internal ListBox into some other type, such as ListView, in order to add some functionality.
In this scenario, if you create a method called DisableList on the form, you will only have to change one place in code, to update the way the list should be disabled.
But if you choose the method of writing code such as _client.listbox1.Enabled = false;, you will have to go through all the pieces of code that touch the ListBox, and update them.
A very important principal in design is to avoid exposing the internal implementation details of class to those that have to use it. In this case, you will benefit if the parent form won't have to know that the list is implemented as a ListBox.
Every time when I change some values in form controls, I need to set a property of an object or vice versa. Instead of writing some methods for each control, I want a general solution for GUI elements. I do not use WPF but only C# 3.0.
Any suggestions?
Thanks.
All controls expose events that signal that their value changed. You can subscribe to it and change another control's value.
You could make the object a field in your form. When the relevant event fires from a control, then call the appropriate operation on the object.
Alternatively, have a Presenter/Controller object that stores your form as a field. It could take it as a parameter in it's constructor. This presenter can then subscribe to your form's relevant events and act appropriately. You could go further with this and extract an interface from your form and program to that in the presenter instead which would help testing. Have a look at the MVP pattern.
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.