Both controls are just about an onion skin around an inner structure. But there is one main difference: The control class helps you to implement the OOP principle of encapsulation. It's thought of the base class to create complexer controls with a sub structure, while to the outside world it technically has no inner structure.
Especially with the final class based on the control class put on a form, you cannot adress the inner structure from outside. If you put a label and a textbox in a container you can adress these inner controls with eg Thisform.mycontainer1.text1/label1, but with the control base class Thisform.mycontrol1.text1 would fail. Text1 is like a protected property.
The intention is, that you put everthing public on the container level, eg add a caption and a value property on the control level, then if one of these is set, forward that to the caption and value of the inner textbox and label. So from outside it will look like one monolithic control. You can change the inner structure if needed, and the outer control will still work the same way.
This said, it's not much of an advantage. While it helps to enforce the encapsulation, and keeps the inner workings of a control internal, the more complex foxpro base controls don't work that way for good reasons: It would be hard to work with grids, if you couldn't adress inner subobjects of it like headers, columns and column's current controls from code outside of a grid, eg from form methods.
If you're still puzzled by this explaination, I'd rather recommend to use the container. I haven't seen any important implementation of a complexer control based on the control class.
Even in the aspect of encapsulation the control class has a design flaw: SetAll does perforate it and set's the inner objects of a control, even those properties you may not want exposed, thus the main idea of encapsulation and protection is broken.
Olaf, thank you for your excellent explanation. I can't see much difference either, except that you are unable to edit objects contained within a control class, but I don't consider that an advantage.
I can't add much to Olaf's insightful explanation. But, for what it's worth, in my 12 years with VFP, I've never used a Control class and never seen a good reason to. That does not mean there is anything wrong with using that class. More likely, I've never considered the issue deeply enough.
Rightly or wrongly, I tend to use the following:
- Container. Especially when working in the visual class designer, or when the purpose of the object is to contain other objects. For example, I've got a custom calendar class that consists of a text box and button (click on the button and a calendar pops up). These are held together in a container.
- Custom. I tend to use these for global services. Examples include my global form manager that handles communication between forms. They are usually written as PRGs and have no user interface.
- Session. Similar to custom, but especially useful if the class is to have a private data session. An example is my user manager, which needs to access the users table to return information about a user's status and security settings. By giving it its own data session, it doesn't need to worry about other parts of the application using that table.
I don't claim the above is necessarily the best practice, and it might not be the best solution in all cases, but it has worked well for me.
Mike
__________________________________
Mike Lewis (Edinburgh, Scotland)
you could also consider not being able to change protected properties from outside of a class as a disadvantage. In OOP this is considered a good thing. And so is encapsulation within a control class in that respect.
Not every group of controls/subobjects is making up a new control, therefor even if I'd make use of the control base class I wouldn't do for all groups o subobjects.
Being able to edit objects within a container as opposed to a control class may be a good thing. But thinking about the OOP principle of encapsulation you're thereby creating a dependancy between the container and the outside world. The container is not self contained and responsible for itself alone anymore.
Changing something with the container class alone, eg removing or renaming some inner object, you break the outside code that accesses this inner object. Or you need to change the container class AND some other class working with something inside the container.
That's the bad thing about the advantage of being able to edit the inner objects of containers. Why should any code outside of the container be able to change something inside the container? Shouldn't a container be slefcontained? If not, then why group something with it at all, you could then also put single objects directly on the form without a container around it.
You can have selfcontained and fine OOP code without using the control base class for this enforcement of encapsulation. You're tempted to do hacks if you can access the inner structure, you're just createing a bigger scope of encapsulation less maintainable and more monolithic.
But you can also play to the rules with a container object and you can use even more advanced design patterns like a mediator to handle the inside of containers. Using a control base class will not enable you to have a seperate mediator. The control itself would be the mediator, handling the inside/outside communication.
If you don't get me I suggest reading a bit about design patterns -
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.