Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

WP7 - adding a ‘Fade to Black’ effect to a ListBox

DZone's Guide to

WP7 - adding a ‘Fade to Black’ effect to a ListBox

· Mobile Zone
Free Resource

Download this comprehensive Mobile Testing Reference Guide to help prioritize which mobile devices and OSs to test against, brought to you in partnership with Sauce Labs.

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.

Analysts agree that a mix of emulators/simulators and real devices are necessary to optimize your mobile app testing - learn more in this white paper, brought to you in partnership with Sauce Labs.

Topics:

Published at DZone with permission of Alessandro Giorgetti, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}