I wanted to have a small and ‘nice’ application in which to experiment things related to networking and graphic effects in WP7, so I took out the ‘My WP7 Brand’ project from CodePlex and started to customize it, this is how ‘All About PrimordialCode’ is born.

Let’s start reminding you I’m not a designer, like many of you I’m a developer.

The first thing I want to show you is how I realized a ‘fade to black’ effect for a ListBox, requisites:

  • Items that are scrolling out of the ListBox visible area have to fade away gently, not with an abrupt cut.
  • The ListBox have to maintain its full and normal interactions as much as possible.
  • It has to work with dark and light themes.

Here are the final results:

FadingListBoxWhiteFadingListBoxDark

Figure 1 and 2: fading effect on a light and dark theme.

The straightforward way to obtain those result is to use and ‘OpacityMask’ like in the following code:

<ListBox Margin="0,0,-12,0">
	<ListBox.OpacityMask>
		<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
			<GradientStop Offset="0" Color="Transparent" />
			<GradientStop Offset="0.05" Color="Black" />
			<GradientStop Offset="0.95" Color="Black" />
			<GradientStop Offset="1" Color="Transparent" />
		</LinearGradientBrush>
	</ListBox.OpacityMask>
	<ListBox.ItemTemplate>
		<DataTemplate>
			...your incredible item template goes here...
		</DataTemplate>
	</ListBox.ItemTemplate>
</ListBox>

Pretty easy and straight to understand. It only has a small drawback on WP7: the horrible rendering performances when you scroll your list elements (do not trust the performances of the emulator when it comes to graphics...try it on a real device!). The user experience is that bad on a large ListBox that I decided to drop this way of doing things in favor of a small ‘hack’.

The solution is simple: draw two small rectangles OVER the ListBox, anchored to the Top and Bottom borders. Set the correct OpacityMask for those rectangles. To have a ‘cleaner’ solution I extracted the ListBox template using Blend and I defined a brand new style based on the default one:

<Style x:Key="FadingListBox" TargetType="ListBox">
	<Setter Property="Background" Value="Transparent"/>
	<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
	<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
	<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
	<Setter Property="BorderThickness" Value="0"/>
	<Setter Property="BorderBrush" Value="Transparent"/>
	<Setter Property="Padding" Value="0"/>
	<Setter Property="Template">
		<Setter.Value>
			<ControlTemplate TargetType="ListBox">
				<Grid>
					<ScrollViewer x:Name="ScrollViewer" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" Padding="{TemplateBinding Padding}">
						<ItemsPresenter/>
					</ScrollViewer>
					<Rectangle VerticalAlignment="top" Height="15" Fill="{StaticResource PhoneBackgroundBrush}">
						<Rectangle.OpacityMask>
							<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
								<GradientStop Offset="0" Color="Black" />
								<GradientStop Offset="1" Color="Transparent" />
							</LinearGradientBrush>
						</Rectangle.OpacityMask>
					</Rectangle>
					<Rectangle VerticalAlignment="bottom" Height="15" Fill="{StaticResource PhoneBackgroundBrush}">
						<Rectangle.OpacityMask>
							<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
								<GradientStop Offset="0" Color="Transparent" />
								<GradientStop Offset="1" Color="Black" />
							</LinearGradientBrush>
						</Rectangle.OpacityMask>
					</Rectangle>
				</Grid>
			</ControlTemplate>
		</Setter.Value>
	</Setter>
</Style>
In this style I encapsulated the standard ListBox template inside a Grid, the important bits to realize the fading effect are the lines 16-31.

Having defined the style the usage is trivial:

...
<ListBox Margin="0,0,-12,0" Name="xxx" Style="{StaticResource FadingListBox}">
...

and the performances while scrolling are good again, you just loose two small sensitive area (the two rectangles) in which the user is not able to interact with the ListBox.

If you know a better and more clean way to achieve the same result, please show me it will be greatly appreciated.

Related Content