Thursday, November 13, 2008

Content Control vs Content Presenter

I ran into a problem with how some of my controls were displayed in Silverlight recently. I had created my own extender panel back in Silverlight 2 Beta 2. It turns out it was much the same as the one that has now been released in the Silverlight Control Toolkit. But when Silverlight 2 was finally released recently, my control went from looking like this...



... to looking like this ...


Basically, my content area shrank to nothing. Yes, something changed between the beta and the release, but complaining about it wasn't going to solve my problem so I started trying to figure out how to bring my code back in line.

Fortunately, the control toolkit was also released at the same time. I took a look at the Expander control and realized that I wasn't displaying my content the best way. There seem to be two ways to show content in a content control: use another content control or use a content presenter. The latter is a much better way and the changes are minimal.

To fix the problem I changed my XAML in generic.xaml from this...

<ContentControl
Grid.Row="1"
Content="{TemplateBinding Content}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />

... to this...

<ContentPresenter
Grid.Row="1"
Content="{TemplateBinding Content}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>

And all was once again well. There are many other values I could bind to here including the alignment values, but that was not the focus of this post so I simplified it. The point is that when creating your own content control, you want to use ContentPresenters to display the content. Chances are very good using the ContentPresenter is the recommended approach. But that doesn't stop many people from giving examples using the ContentControl, and I just happened to find one of those examples first.
[Edit]
This is becoming a popular post so I decided to revisit it. Memory told me that this wasn't well written. After a re-read wowever, I realize the only thing that I can really do is explain the issue a different way.
When creating a custom control that you want other developers to be able to determine the contents of, it is easiest to extend ContentControl. ContentPresenter is what is used to show the definition of the Content DependencyProperty within the content control. It is possible to achieve the same effect without extending ContentControl, but then you need to explicitly define your Content DependencyProperty.
Also, if you have multiple content areas within your control (e.g., a title area and data area), you can either use a ContentControl and define the second DependencyProperty or you can extend Control and define both Content properties yourself (e.g., TitleContent and DataContent).
I hope this edit makes things more clear.
[/Edit]

No comments:

Post a Comment