User Controls as Objects
ASP.NET developers don't fully exploit User Controls -- until they start thinking of them as "User Interface" objects.
User Controls reveal their true power when you put one on a page and let it interact with the other parts of the page. However, to get your User Controls to interact with the other controls on the page, you need to think of them not as little Web pages but as objects that happen to display a user interface.
Loading User Controls
While you can drop a User Control onto a page at design time, you can also load a user control onto the page at run time just as you would any other object. However, you don't use the New keyword to load a User Control. You use the Page's LoadControl method:
Dim myc As MyControl
myc = CType(Me.LoadControl("MyControl.ascx"), MyControl)
Unlike other objects, since a User Control displays part of your user interface, you need to get your User Control onto the page. The easiest way to do this is to put a Panel on your page and add your control to the Panel's Controls collection:
Always add the User Control to the page in the Page's PreInit event. When a user clicks on a submit button in the browser, the data on the page is gathered up and sent back to the server. Back on the server, ASP.NET retrieves the page and recreates all of the design-time controls before the PreInit event fires; after the PreInit event fires, the ASP.NET slots the data that came up from the browser into the appropriate controls on the page. If you haven't added your User Control to the page in the PreInit event, then you won't get the data that comes up from the browser.
Methods, Properties and Events -- Oh, My!
To fully act as an object, though, your control needs to provide an interface that exposes methods, properties and events. Exposing methods is easy: Just declare your subroutines and functions with the Public keyword. Creating Properties is equally easy since each property routine consists of a Get routine (which looks like a function) and a Set routine (which looks like a subroutine).
It's Events that make developers nervous. I had a question from a reader recently who had a User Control with one button on his User Control for each letter of the alphabet. The problem was how to notify the host page for the User Control when each button was clicked. The easiest solution is to have the User Control fire an event that notifies the host page that one of the buttons was pressed and pass the letter represented by the button.
That requires enough of an explanation that I'll have to leave that for my next column. Instead, I'll finish up by looking at a more mundane problem: avoiding writing one event procedure for each button.
When a developer adds a button to a page, typically the next thing the developer does is double-click on the button to create an event handling routine for the button's Click event. It's not necessary to create a separate Click event routine for each Button because you can wire up a single event routine to as many controls as you want.
In C#, you don't even need to write any code to make this happen. First, drag one button onto the page and double-click it to create its Click event routine. After the routine is created, copy the event routine's name (e.g., "MyButton_Click"). Then return to your .ASPX file and drag your second button onto the page. Once the button is on the page, go to the Properties Window for the button, switch to the Event list and paste the name of the first routine into the Click event property for the second button. Repeat this for all of the buttons on the page and all of your buttons will now be calling the same routine.
In Visual Basic, it's actually easier but you have to write some code. Drag all of your buttons onto the page and then double-click on the first one. Once the first event routine is created, go to the end of the event's line where you'll find something like "Handles MyButton.Click." Type a comma and add the name of your second button and its event to give something like this:
...Handles MyButton.Click, MyNextButton.Click
You can keep adding Button Click events to this single routine as long as you separate each Button event name from the previous one with a comma.
Of course, you'll want to know inside the routine which button called it -- but I'll cover that in the next column also.
Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.