Silverlight 2 gives you the ability to create your own controls. The term custom control has been thrown around a lot in the Silverlight community, but it’s not always clear what that means. Here are my thoughts.
There are three types of controls that you can create:
· User controls
· Templatable controls
· Everything else
In my opinion, the list above is ordered from easiest to create to hardest, in terms of time and required knowledge. This post will attempt to explain what each type is and when it is useful.
User controls inherit from the UserControl class. If you’ve created a Silverlight project in Visual Studio (or Blend), you might have noticed that the root element of the page.xaml file is <UserControl>. Because UserControl is the most common class that acts as the root of Silverlight applications, I consider the UserControls to be self-contained, almost “black box” entities. There are very few ways that an application can programmatically interact with the UserControl, unless the control author explicitly adds functionality by defining methods or properties that the application author can call or set.
The UserControl class inherits from the Control class and defines one meaningful property, Content, which is protected. The Content property is populated when the control author “builds” the UserContol. In the overly simple XAML that follows, the StackPanel that is the child element of the UserControl becomes the value of the UserControl’s Content property.
<TextBlock FontSize=”18″ Text=”Enter your name.”/>
You cannot easily get to the elements within the user control. (You can get to them, but the UserControl class isn’t designed to be used that way.) Likewise, application authors who use the control shouldn’t change the control’s contents. That is, if a UserControl is added to an application, the application cannot change what’s inside of it. This is why I think of UserControls primarily as black boxes. An application can interact with or change the UserControl only if the UserControl author adds such functionality.
In fact, I consider the UserControl to be more restrictive than the other controls that inherit from the Control class. Why? Because the Control class defines the Template property. This property allows applications to restructure the appearance of a control. Here is an example that creates a new ControlTemplate for a CheckBox. For more information about creating ControlTemplates, see Customizing the Appearance of an Existing Control by Creating a ControlTemplate. Although the UserControl inherits from Control, you cannot set the Template property of a UserControl. If you try to do so, an exception is thrown. Because of this, I consider UserControls less functional than even the controls that ship with Silverlight. This also brings us to the next type of control, the templatable control.
A templatable is any control that inherits from the Control class or any of its subclasses other than UserControl. When you create a templatable control, you enable application authors to customize your control’s appearance beyond just setting properties. Creating a Control That Has a Customizable Appearance explains the practices you should follow when you create a templatable control, so I’m not going to explain how to create a templatable control here. However, I will mention a couple key points:
1. When you create a templatable control, you define the control’s appearance in its Template property. Building a template is much like building anything else in Silverlight. Here is an example of the control with the same appearance as the UserControl.
<TextBlock FontSize=”18″ Text=”Enter your name.”/>
Now someone can change how the control looks.
2. The control’s appearance can be customized in tools like Expression Blend if you follow the Parts and States model. Essentially, the parts and states model specifies that you use a ControlTemplate to define a control’s appearance, and specifies what parts need to be included in the ControlTemplate. In the preceding example, someone might want to provide a new ControlTemplate, but the Control might rely on there being a TextBox called firstName in the template. The parts and states model specifies how a control author communicates that requirement and is explained in Creating a Control That Has a Customizable Appearance.
Controls that don’t inherit from Control or UserControl fall into this category. It’s important to keep this in mind because the Control class is where ControlTemplates are introduced. Elements such as Canvas and StackPanel don’t have ControlTemplates, so you can’t customize their appearance the way you can for controls like CheckBox and Button. Sometimes you might need to create a special control when adding elements to a Template or to the Content of a UserControl isn’t sufficient. That’s very valid, but realize that if you write a control that inherits from Panel, you are not creating a templatable control.
“Custom” Controls Revisited
I deliberately did not use the term “custom control” to describe one of the three categories because lately I have come to feel that the term is not meaningful enough. After all, one could argue that every time you build a control, you are creating a custom control. I’ve found a couple of blogs where control authoring has been divided into two categories: user controls and custom controls where anything that is not a user control is a custom control. I think it’s important to divide the controls further into the three categories that I’ve discussed here.
Because each scenario is different, it is hard to give concrete advice about which decision is best, but I’d start with looking at whether an existing control has similar functionality, and inherit from that, regardless of what category the control falls into. For example, if you want your control to contain another UIElement, consider using the ContentControl. A ContentControl can contain any type of object–StackPanel, Button, String, DateTime, a custom CLR object–anything! The advantage of using a ContentControl over a UserControl is that the Content property is public, so applications can put anything they want to in there. A ContentControl also uses a ControlTemplate, so you can define the appearance of the control in the Template and still allow applications to add content to your control.
The one case when you might create a UserControl rather than a templatable ContentControl is if you don’t want applications to change the control’s appearance other than adding the content. But if you create a UserControl, you must also define the property that contains the piece that can be added by the application, because the UserControl’s Content property is protected.
Hopefully, this post has shed some light on the different types of controls you can make in Silverlight, what the differences are, and which type of control you should create for your particular situation.