Silverlight UI Rant #2 – ListBoxItem

Tonight’s recipient of my UI Rant is the Silverlight 2 ListBox, or more specifically, the ListBoxItem.  A client recently asked me to provide an alternating row style like the DataGrid for the ListBox.  Now, if you’ve ever tried to add a border or background to your ListBoxItem, you’ve seen this:

No problem, you say, I will simply set the HorizontalContentAlignment of my ListBox to Stretch and all should be good.  When that doesn’t do it, you’ll probably try creating/editing the ListBox’s ItemTemplate….maybe adding a Grid and setting its HorizontalAlignment to Stretch.  This too will fail.

Turns out, the problem is not with your ItemTemplate or even with the ListBox itself.  The issue is in the container that actually contains your Item and that is the ListBoxItem.  The property on the ListBox that allows you to set a custom style for this ListBoxItem is called ItemContainerStyle.  Armed with this information, you quickly throw together a style for your ListBoxItem, maybe like so:

<Style TargetType=”ListBoxItem” x_Key=”ItemContainerStyle”>
<Setter Property=”Padding” Value=”3″ />
<Setter Property=”HorizontalContentAlignment” Value=”Stretch” />
<Setter Property=”VerticalContentAlignment” Value=”Top” />
<Setter Property=”Background” Value=”Transparent” />
<Setter Property=”BorderThickness” Value=”1″ />
</Style>

And then add that to your ListBox, like so:

<ListBox Margin=”8,8,10,8″ x_Name=”defaultListBox” ItemsSource=”{Binding}”
ItemTemplate=”{StaticResource EmployeeItemTemplate}”
ItemContainerStyle=”{StaticResource ItemContainerStyle}”/>

Hit F5 and just about the time you congratulate yourself on solving this, the Silverlight Loading Animation will finish and you’ll discover that your ListBox still looks exactly like the original screenshot above.  So, what happened?

What happened is that the default ControlTemplate for the ListBoxItem has its HorizontalAlignment hard-coded to Left and no matter what you do when setting the properties, it will always b
e Left.  If you
‘ll do a little diving into the full default style for ListBoxItem, courtesy of SilverlightDefaultStyleBrowser (highly recommended), you’ll see exactly what I’m talking about in the ContentPresenter’s HorizontalAlignment property:

The good news is that because you have the ability to replace the Template of any control in Silverlight, you can simply “correct” this hard-coded problem by replacing the hard-coded Left value for HorizontalAlignment with {TemplateBinding HorizontalContentAlignment}, so your final new Style would look like this:

<Style TargetType=”ListBoxItem” x_Key=”StretchedItemContainerStyle”>
<Setter Property=”Padding” Value=”3″ />
<Setter Property=”HorizontalContentAlignment” Value=”Stretch” />
<Setter Property=”VerticalContentAlignment” Value=”Top” />
<Setter Property=”Background” Value=”Transparent” />
<Setter Property=”BorderThickness” Value=”1″ />
<Setter Property=”TabNavigation” Value=”Local” />
<Setter Property=”Template”>
<Setter.Value>
<ControlTemplate TargetType=”ListBoxItem”>
<Grid Background=”{TemplateBinding Background}”>
<vsm:VisualStateManager.VisualStateGroups>
<!– removed VSM code for brevity  –>
</vsm:VisualStateManager.VisualStateGroups>
<Rectangle x_Name=”fillColor” Opacity=”0″ Fill=”#FFBADDE9″ IsHitTestVisible=”False” RadiusX=”1″ RadiusY=”1″  />
<Rectangle x_Name=”fillColor2″ Opacity=”0″ Fill=”#FFBADDE9″ IsHitTestVisible=”False” RadiusX=”1″ RadiusY=”1″  />
<ContentPresenter x_Name=”contentPresenter” Content=”{TemplateBinding Content}” ContentTemplate=”{TemplateBinding ContentTemplate}” HorizontalAlignment=”{TemplateBinding HorizontalContentAlignment}” Margin=”{TemplateBinding Padding}”  />
<Rectangle x_Name=”FocusVisualElement” Stroke=”#FF6DBDD1″ StrokeThickness=”1″ Visibility=”Collapsed”  Ra
diusX=”1″
RadiusY=”1″  />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Now your ListBoxItem will respect the value you are setting for its HorizontalContentAlignment in your Setter above and your ListBox will finally look like this:

Hope that saves someone a little frustration.  I’ll continue on to adding the alternating row style in another post.

Here is the live sample.

Here is the source code.

Rik Robinson

Recent Posts

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

6 days ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

3 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago

Mastering Compliance: The Definitive Guide to Managed Compliance Services

In the intricate landscape of modern business, compliance is both a cornerstone of operational integrity…

2 months ago