Een van de fundamentele doelen van Silverlight en WPF op gebied van ontwerpen is programmeurs in staat stellen om de UI functionaliteit op een eenvoudige manier te vervatten in herbruikbare controls.
Enerzijds kan je nieuwe custom controls implementeren door een klasse te creëren uit een van de bestaande Control klassen (zowel een Control base klasse als een control zoals een TextBox, Button, enz...). Anderzijds is het mogelijk om herbruikbare User Controls te maken - waardoor het eenvoudig wordt om een XAML opmaakbestand te gebruiken om de UI van een control op te stellen (en waardoor ze super gemakkelijk te maken zijn).
In deel 6 van mijn digg.com tutorial blog serie, toonde ik aan hoe je een nieuwe user control moet aanmaken met het "Add New Item" project item dialoog in VS 2008 om dan vervolgens het UI erin te definiëren. Deze aanpak werkt zeer goed als je vooraf al weet dat je een UI in een User Control wil vervatten. Je kunt dezelfde techniek ook toepassen in Expression Blend.
Een bestaande UI in een User Control vervatten
Soms weet je vooraf niet helemaal zeker of je iets van de UI functionaliteit in een herbruikbare user control wil vervatten. Je beslist pas om dit wel te doen als je al begonnen bent met het definiëren van een bovenliggende pagina.
Een voorbeeld: we werken aan een formulier waarin we willen dat een gebruiker zijn verzendings- en betalingsgegevens invoert (Shipping and Billing). We beginnen UI te creëren waarin we de adresgegevens (Shipping) vervatten. Om dit te doen, zouden we een <border> control kunnen toevoegen aan de pagina, genesteld in een grid layout panel (met 2 kolommen en 4 rijen), om dan de labels en textbox controls erin te plaatsen:

Nadat we alles nauwkeurig hebben ontworpen, beseffen we opeens: "hmm, we zullen exact dezelfde UI gebruiken voor de betalingsgegevens (Billing). Misschien maken we beter een address user control aan dat geschikt is voor hergebruik om te vermijden dat we in herhaling vallen".
We kunnen natuurlijk de aanpak van de "Add New Item" project template toepassen om een nieuwe lege user control aan te maken, en dan kopiëren en plakken we gewoon de bovenliggende UI inhoud erin.
Maar een nog snellere techniek die we kunnen toepassen in Blend is eenvoudigweg de controls selecteren die we als user controls willen vervatten in de designer. Vervolgens rechtermuisklik en kiezen voor "Make Control" menu optie :

Als we het “Make Control” menu item selecteren zal Blend ons de naam van de te creëren User Control vragen:

We noemen deze nieuwe control "AddressUserControl" en klikken op OK. Nu zal Blend een nieuwe User Control aanmaken met de inhoud die wij selecteerden :

Als we het project heropbouwen (Project / Rebuild Project), en teruggaan naar de originele pagina, dan zullen we dezelfde UI zien als voordien, behalve de UI voor het adres dat in de AddressUserControl vervat is.

We zouden de eerste AddressUserControl “ShippingAddress” kunnen noemen, en dan een tweede versie van de user control toevoegen aan de pagina om het betalingsadres in op te nemen (we noemen deze tweede versie “BillingAddress”):

Als we nu het uiterlijk van onze adresgegevens willen veranderen, dan hoeven we dit maar op één plaats te doen. De andere controls zullen automatisch mee worden aangepast.
Data verbindende Address Objecten naar onze AddressUserControl
Nu we over enkele user controls beschikken die onze adres UI’s bevatten, kunnen we een Addresss data model class creëren die we kunnen gebruiken om ze aan elkaar te verbinden. We definiëren de classes zoals hieronder (we gebruiken hiervoor de automatic properties language feature) :

Daarna kunnen we in de achterliggende code van het Page.xaml bestand twee versies van ons Address Object concretiseren- één voor het verzendingsadres (_shippingAddress) en één voor het betalingsadres (_billingAddress) - in dit voorbeeld gebruiken we fictieve data. Vervolgens zullen we de Address objecten verbinden met onze AddressUserControls op de pagina. We doen dat door de "DataContext" eigenschap op elke user control te positioneren op de juiste address data model versie van _shippingAdress of _billingAddress (zie onderaan de private void BinAdressModels):

We zijn aan de laatste stap toegekomen. Nu moeten we de {Binding} statement declareren in ons AddressUserControl.xaml bestand. Dat zal een relatie van tweerichtingsdatabinding leggen tussen onze “Text” eigenschappen van onze TextBox controls in onze User Control en de eigenschappen van de Address data model objecten dat we verbonden hebben aan de User Control :

Als we op F5 drukken om onze applicatie te testen, zullen we nu de automatische dataverbinding zien van de Address data model objecten met onze AddressUserControl :

Omdat we de {Binding} declaratie ingesteld hebben als “Mode=TwoWay”, zullen wijzigingen die gebruikers maken in de tekstboxen automatisch doorgevoerd worden naar de Address data model objecten (er is geen code nodig voor deze actie).
We kunnen bijvoorbeeld ons origineel verzendingsadres (Shipping Address) in de browser veranderen naar Disneyland:

Als we een debugger breakpoint plaatsen op de “Click” event handler van de “Save” knop SaveBtn_Click (en dan op die knop klikken), kunnen we zien hoe de bovenstaande aanpassingen in de Tekstboxen automatisch weerspiegeld worden in ons “_shippingAddress” data model object :

Dan zouden we de SaveBtn_Click event handler kunnen implementeren om de Shipping en Billing Address data model objecten aan te houden zoals we het zelf willen, zonder ooit manueel iets te moeten ophalen uit of manipuleren in onze UI control op de pagina.
Deze goede view/model scheiding die ondersteund wordt door WPF en Silverlight, maakt het mogelijk om later nog de UI van de AddressUserControl te veranderen zonder enige code te moeten veranderen in de pagina. Ook wordt het mogelijk om gemakkelijker de unit test op de functionaliteit toe te passen (lees mijn laatste post over Silverlight Unit Testing om hierover meer te weten te komen).
Samenvatting
Met WPF en Silverlight wordt het heel gemakkelijk om de UI functionaliteit te vervatten in controls. Het user control mechanisme dat ze ondersteunen biedt een heel eenvoudige manier om hier optimaal van te profiteren. Door user controls te combineren met verbindingsfuncties (binding) zijn er mooie scenario’s mogelijk voor view/model scheiding waardoor je zeer pure code of “clean code” kan schrijven wanneer je met data werkt. Je kunt een afgewerkte versie van het bovenstaande voorbeeld hier downloaden als je het wilt gebruiken op je eigen computer.Om meer te leren over Silverlight en WPF, ga dan zeker eens kijken naar mijn Silverlight Tutorials and Links Page . Ik raad ook zeker de fantastische MIX08 sessie van Karen Corby aan (waarin je meer kan leren over User Controls, Custom Controls, Styling, Control Templates en meer). Je kunt die sessie hier online en gratis kunt bekijken.
Ik hoop dat je hiermee aan de slag kan!
Scott