AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1860&pId=-1
Using the Silverlight HeaderedContentControl
page
by Brian Mains
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 27039/ 39

Introduction

The Silverlight toolkit is an add-on to Silverlight meant to add additional Silverlight control functionality for developers.  One of these controls is the the headered content control, a pretty simple control: it consists of a header area and a content area, which the header and content can be anything.  This header/content area is a one-to-one mapping; there is only one header and one content area.

While I'm going to write about this control, I'm also going to discuss the nuances of the content-based controls, how they can be bound, and how the entire control can be bound using an underlying data context.

The Silverlight toolkit is available at http://www.codeplex.com/Silverlight.  This control is subject to change in the future, and may change with the release of Silverlight 3.

Understanding Content Controls

If you've seen a control with the Content property in Silverlight (which there are many), then you see one of the most common types of controls in the framework.  Content controls can take a variety of values in its content property.  In its simplest form, the content of the control could be text or some other primitive value (integer, etc.).  But content controls are not just limited to primitive data.  Content controls can accept any type of other Silverlight element within itself.  This is done by using long-hand syntax in the fom of:

Listing 1: Long-Form Syntax

<HeaderedContentControl.Content>
      <TextBlock Text="My Content" />
</HeaderedContentControl.Content>

In this way, the content property can store another Silverlight element, but it can only store a single element.  This may seem like a bad idea or even a bug, so how do you get around storing more than one element?  You could use a custom control or a user control, but at its simplest form, it could be using a panel control, as in:

Listing 2: Using a panel for content

<HeaderedContentControl.Content>
      <StackPanel>
             <TextBlock Text="My" />
            <TextBlock Text="Content" />
       </StackPanel>
</HeaderedContentControl.Content>

While content controls have only one child, panel-based controls or items-based controls, can store multiple children.  So this type of element meets this one control requirement, and the panel itself can store multiple elements.  It's a two-step process of sorts.  This feature isn't unique to the HeaderedContentControl object, but is a construct in Silverlight (and is also available in WPF).

Data Binding

Silverlight controls support binding to data, whether it be a single or collection of business objects, or a DataTable.  How you bind, though, depends on the control you are using.  Some controls may implement an ItemsSource property.  This property comes from a special base class in the Silverlight framework, and won't be discussed here.  This type of control is more for controls that have a repeatable interface (like the ListBox).  However, controls that do not implement this property can also be bound.

By default, controls can be supplied an underlying data source via the DataContext property.  This property specifies an object or collection that acts as the relative data source, or the data that's associated with the control.  What does that mean in the case of the HeaderedContentControl?  Let's take a look.

One of the ways to supply this value is via code, as in Listing 3.  I like to reference my data via code, and skip the inline capabilities of referencing data.

Listing 3: Supplying a DataContext

This.HeaderedControlInstance.DataContext = myObj;

This control now knows about the object being referred to it.  So any {Binding} statements within the header and content templates come from data supplied from the object assigned to DataContext.

However, if you tried to implement this as is based on my description of the solution, and expect it to work, it won't bind correctly (it appears blank).  This is because there is one other step that needs to happen.  A generic {Binding} statement needs assigned to the Header and Content properties; this correctly passes the underlying object supplied to the DataContext property to the header/content templates.  The final representation of the control would appear as:

Listing 4: Binding in the Header/Content Templates

<HeaderedContentControl Header="{Binding}" Content="{Binding}">
      <HeaderedContentControl.HeaderTemplate>
             <Label Content="{Binding Title}" />
      </HeaderedContentControl.HeaderTemplate>
      <HeaderedContentControl.ContentTemplate>
             <Label Content="{Binding Text}" />
      </HeaderedContentControl.ContentTemplate>
</HeaderedContentControl>

In Listing 4, the Headered Content Control receives an object (via the DataContext) that has a Title and Text property, which is supplied to the Header/Content templates via the binding in the Header/Content properties.  The Title and Text values in the bound object are bound to labels, via the Binding statement.  The value in the Binding declaration has to match the property in the underlying object.

So what's the difference between "{Binding}" and "{Binding Title}"?  In the latter option, Title has to be the name of a property that's being bound to some control.  The binding statement without a parameter, the former option, binds the whole object to the control.  So the whole object is bound to the Header/Content of the control, so individual properties can be bound.

Items Binding

So what if you want multiple items within the Header/Content?  You could use an ItemsControl, like the HeaderedItemsControl class.  This control already provides this ability with ease.  However, using the HeaderedContentControl, the solution can also be to use an ItemsControl within the content.  To setup this example, suppose you had the following:

Listing 5: Example Class

public class SampleClass
{
      public string Title { get; set; }
      public string Text { get; set; }
      public List<SampleItem> Items { get; set; }
}
Public class SampleItem
{
      public string Name { get; set; }
      public string Value { get; set; }
}

Using a similar setup previously for the header/content, the solution to binding a repetitive list within the HeaderedContentControl control is to use a repetitive control (like the ListBox control) within the content.

<HeaderedContentControl Header="{Binding Title}">
      <HeaderedContentControl.Content>
            <ListBox ItemsSource="{Binding Items}">
                  <ListBox.ItemTemplate>
                        <DataTemplate>
                              <StackPanel>
                                    <Label Content="{Binding Name}" />
                                    <Label Content="{Binding Value}" />
                              </StackPanel>
                        </DataTemplate>
                  </ListBox.ItemTemplate>
            </ListBox>
      </HeaderedContentControl.Content>
</HeaderedContentControl>

In this example, the ListBox control is a way to show multiple items within the content.  The source of the content comes from the Items property in the SampleClass class.  Any items in this list is bound to the ListBox, which each item gets its own instance of the provided DataTemplate, binding each SampleItem object to the created template for the ListBoxItem.

Conclusion

The HeaderedContentControl is a simple control that provides a header and content.  As we see from content-based controls, we still can provide flexibility using these simple controls to do more advanced layouts that we may need to be accustomed to.

The HeaderedContentControl class provides a header and content to display data in, but also provide a template for each, which allows binding to these templates via an object bound to the DataContext property.



©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-28 4:31:18 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search