- Home
- General
- General Chat
IDE defaults are wrong?
Joined: 12-Jul-2004
I currently have the following setup: A (login) form with a usercontrol docked inside covering the most of the form except for a OK and a Cancel button. This usercontrol has more controls inside: a combo and some textboxes with labels. Next I fill the combo on the usercontrol with a collection from LLBLGen Pro.
I first did this in the form load event and naturally all goes fine: the data is viewable inside the combo. I can select one of the rows in the combo, fill the other textboxes and press the OK button to login.
Currently I am doubting if the filling of the combo needs to be done inside the form and not inside the usercontrol's load event. I have always learned to build somewhat towards "stand-alone" components, and I feel this usercontrol is one. So if the usercontrol can maintain its own content, it should, IMO.
Going on from this... why does the IDE declare the controls on a form as Friend? Again thinking of a form as a stand-alone component they should be private and only expose thinks really needed by outsiders. I have skimmed some usergroups on this subject and found someone saying that c# does declare them as private, while vb.net does not: is this true? They also said that this was because of vb.net its background: vb programmers were used to have public access. Does it harm the declare controls on a form as private and if outsiders need any data stored as private inside the form, make that data accessible through a property or a function.
So to conclude, I really would love to get some feedback and this, as I think the defaults are just wrong seeing it from my point of view (programming towards components).
TIA,
Michel van den Berg
Joined: 04-Feb-2004
Step 1, run FX Cop on your code and see what you find.
In vb.net friend is the same thing as internal in C#, i.e. only files in the same assembly may access the fields.
I think you will find that VB.NET and the CodeDom Breaks many of the best practices laid out in the Microsoft Best Practices Guidelines. Please note that C# isnt exactly perfect at times either, for example, if I had a nickle for everytime my C# event handlers dissapeared from the CodeDom section of an ASP.NET page or control I would be richer than Uncle Billy himself.
Taking your useage scenario into account, I would agree that user controls should really encapsulate their functionality and be black boxes that do what ever they do and signal when they are done. But, user controls still need a host, so, since you are only going to use this user control once, i.e. during login, then you might be just as well to show a modal form.
Once you authenticate the user, you should create some sort of principal, either, windows, generic, passport, or otherwise, and rasie an event out of the form OR user control. The event would ideally be mapped to a delegate higher in the namespace so that other objects could subscribe to the event.
You should probably pass the principal along in the event args so that the subscribers of the event can inspect the principal and render themselves accordingly based on the principal.
Joined: 12-Jul-2004
Wow, great reply with all my questions answered: I thank you a lot for that! I've already installed FxCop so I'll check its report on my code soon. However, I still feel I am uncertain about declaring controls private instead of friend. The only way outsiders can have access to these controls is making a read-only property or function in the usercontrol and then return one. I could however, going on from the previous example, make, like you said an event or perhaps even a Login() function, so that outsiders don't need to access the controls inside the usercontrol. This can be done in many cases I think, but what if outsiders really need to access them. For example, I would like to know which row the combo in the usercontrol currently has selected. I could do one of the following things: 1. Make the control friend. Now I can just do: usercontrol.combo.SelectedRow 2. Make a (read-only) property or function returning the selectedrow and which is named something like SelectedUser (the combo has in this case users). Now I can do: usercontrol.SelectedUser. 3. Make an event called SelectedRowChanged in the usercontrol. This event is called from the same combo event.
I think doing it like 1 would end up as everything being accessible, but very unexpected things can occur as the usercontrol does not have full control anymore. The second way is which I like best: the usercontrol has full control and only exposed things needed. These things needed are based inside more abstract and meaningful accessors which makes things clearer, IMO. However, a usercontrol with many controls can end up in having many of these accessors and if you need another accessor you have to build one again in contrast to the first way where you already have everything accessible. Returning one of the controls through a read-only property will simulate the same result as the first way and be slightly more secure. Still I find this an unsafe solution. The third way is just fine, but only useable if you can create/have an event for the wanted access.
I think I will go for a combination of 2 and 3, and way 2 will not expose controls to outsiders: everything will be accessible through functions or properties. Now please give me your view on this, because I am dying to know how you are doing this. Also please let me know if I am over-doing it, will you?
Many thank you's and sorry for the long reply,
Michel van den Berg
Joined: 04-Feb-2004
I declare my fields as private. So a control is a field. I tend to encapsulate a lot of my code. I try to simplify the visible interface that people using my components see. Realistically, consumers of my user control seldom need access to the entire control, just special bits of it. So the data is exposed via properties. It protects your control from unexpected behaviors and unintended useage and still allows consumers to get at the data.
Wether or not a consumer must ask for the data they need, or they are told when their data is ready is a matter of symantics. If a consumer must ask for the data then they need a field or property that they can access. If they dont care when they get the data, but in the event that they do get it, then an event needs to be raised to them.
I use grids primarily for navigation, i.e. here is a list of accounts in a grid, select one to see details. I also write a lot of MDI forms apps. So I never know what forms might be open at any one time. So assume that you have an account list, each account has a list of orders, a list of owners, and a list of invoices. When the user selects an account, I want to synch the forms containing the orders, owners, and invoices for the currently selected account. I raise an event from the account form and the three subscribers update themselves accordingly. Thus, I prefer the event model.