In almost every web project of any size, you would probably use a lot of user controls to separate the content and UI logic. Many of the user controls are used only at one place in the solution while others are used by various pages and other user controls.
The ones that are used throughout the website needs to be generic and loosely coupled from the context in which they are used. If not, they would contain a lot of code only to cater for the needs of certain pages or other controls in which they are embedded. This is bad.
The rules of object oriented programming apply to ASP.NET just as much as for code libraries, which include loose coupling, encapsulation, high cohesion and polymorphism. This is easily forgotten due to the apparent differences between classic programming and ASP.NET development.
A user control should not contain any context specific code, but only do the one thing that it was designed to. If the control is called AddComments.ascx it should do nothing more than add comments. Look at the name and use it as a guide for what it should do, and equally as important, what not to do.
By making it loosely coupled you gain a lot of flexibility and reusability for the user control. You could even use it in other web projects because it is not dependant on the context in which it lives.
The inner workings of a user control should be kept invisible by the user of that control. That is does simply by making the various members private. The AddComments.ascx control only has to expose two properties and that is Name and Comment. Those properties should be made public and everything else should be kept private.
If the user control has some kind of events like a button click event, that button should not be public so the page can listen for the click event. Instead, you should create a public event that you raise internally from the buttons click event handler. By exposing the button you make it harder to understand and use the control. Here is how to add events.
Keep the control focused on the single task it was built to solve. All the methods should relate to each other in some way, so you don’t end up having generic code in them.
If you don’t, you could end up with a huge class that does a lot of other things than adding a comment. That damages maintainability and removes focus of the real problem that it solves.
If you have more than one user control that exposes some of the same properties because they are used in much the same way, you should consider implementing a common interface. That makes them more flexible for the page to use, because it can treat them as they were of same type.
If they share more than just public properties, then a base class is the way to go. The base class can provide common functionality to be used within the user control, so it doesn’t have to be implemented into every one of them.
Polymorphism is only applicable to user controls that bare resemblance to other user controls within the same website.
Remember to refactor
Refactoring an ASP.NET project is nothing like refactoring C#/VB code in practice. Even though the principles are the same, it is much harder to move pieces of a page into a user control. It is even harder to refactor a user control that has grown to big into smaller controls, because that user control might be used in many places throughout the website. More on ASP.NET refactoring.
By adhering to the principles of object oriented programming when designing user controls, you can maximize the maintainability and reusability of the controls. The key is to remember that despite ASP.NET looks very different from C#/VB code libraries, it is still programming and in programming you code using well proven principles. ASP.NET is no different.
To learn more about object oriented design principles or just to touch up, I found this easy-to-use guide.