Silverlight No Selection ListBox and ViewBox

I wanted to display the list of search terms at the top of my Twitfeed Silverlight app (see below) and highlight the current search term. The obvious way to do this is to databind a ListBox to the search terms collection. I ran into a few things I needed to resolve:

  • ListBox supports selection - ie I can select individual items - I don't want this enabled
  • There's no property on the ListBox to access individual items - how do I highlight a specific term?
  • I wanted to size the ListBox to the window so needed to use a ViewBox as part of the template
  • I wanted the ListBox horizontal

Let's tackle those in reverse - easiest first:

Horizontal ListBox

Easy one - just override the default ItemsPanel with a template such as:

     <ItemsPanelTemplate x:Key="ItemsTemplate1">
        <StackPanel HorizontalAlignment="Center" Orientation="Horizontal"/>
    </ItemsPanelTemplate>

Scale the ListBox with a ViewBox

I struggled with this a bit as I was initially trying to incorporate the ViewBox as part of the ItemsPanelTemplate. In fact you simply override the default Template for the ListBox with a Template such as:

     <ControlTemplate x:Key="Template1">
      <tkt:Viewbox>
        <ItemsPresenter Margin="25,5,25,5"></ItemsPresenter>
      </tkt:Viewbox>
    </ControlTemplate>

Accessing Individual ListBox Items

There are some different options here but I decided to go with adding an eventhandler for the loaded event of individual items which gives me an opportunity to create a collection of ListBox items.

     <DataTemplate x:Key="DataTemplate1">
      <TextBlock HorizontalAlignment="Center" 
                 Foreground="White" FontSize="24" 
                 Text="{Binding}" 
                 Loaded="DataTemplate_Loaded"/>
    </DataTemplate>

In my case, each item is a TextBlock and I simply track them in a List. I also set the first item to the highlight colour as that's the first search to be performed.

   private void DataTemplate_Loaded(object sender, System.Windows.RoutedEventArgs e)
  {
      _displayTerms.Add(sender as TextBlock);

      if (_displayTerms.Count == 1)
      {
          _displayTerms[0].Foreground = new SolidColorBrush(Colors.Yellow);
      }
  }

Disabling Selection

To disable selection you can change the ItemContainerStyle on the ListBox to simplify the ListBoxItem Template. In Blend select the ListBox then select Object -> Edit Other Styles -> Edit ItemContainerStyle from the menu then select Object -> Edit Control Parts (Template) -> Edit Template. Essentially you remove all the transitions and elements associated with selection. I boiled it down to:

     <Style x:Key="ListBoxItemStyle2" TargetType="ListBoxItem">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem">
            <Grid Background="{TemplateBinding Background}">
              <ContentPresenter HorizontalAlignment="Left" 
                                Margin="{TemplateBinding Padding}" 
                                x:Name="contentPresenter" Content="{TemplateBinding Content}" 
                                ContentTemplate="{TemplateBinding ContentTemplate}" />
            </Grid>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

And with that I had exactly what I wanted. Silverlight and XAML make it so easy to customise controls to work just the way you want them to.

Technorati Tags: silverlight,listbox,template,selection