Panorama Tricks – How to eliminate blending seams in the background

If your Windows Phone 7 application includes a Panorama with a background, you may have seen seams—one pixel wide lines darker than the background image’s color—where the background loops around and the right edge meets the left edge, or vice versa. This happens when background is being animated, during panning, flicking, etc., and the background doesn’t happen to be drawn on a whole pixel boundary.

I had a heck of a time trying to get a screen shot of a Panorama with this artifact, since that means I’d need to take a screen shot of the emulator while panning, during a flick, etc. (Actually, I gave up almost instantly.) I was going to draw a picture with Paint, but I think everybody can imagine what a vertical line that goes from the top to the bottom of a Panorama looks like. I bet you can even imagine it flashing while you pan. So let’s move on.

The trick to getting rid of that line is to overlap the edges of the background. And the way to do that is to retemplate the Panorama to use some negative Margin.

Here’s what that XAML looks like:

Code Snippet

  1. <phone:PhoneApplicationPage
  2.     x:Class="SeamlessPanorama.MainPage"
  3.     xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4.     xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  5.     xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  6.     xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  7.     xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
  8.     xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
  9.     xmlns:ctl="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
  10.     xmlns:ctlp="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone.Controls"
  11.     mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
  12.     FontFamily="{StaticResource PhoneFontFamilyNormal}"
  13.     FontSize="{StaticResource PhoneFontSizeNormal}"
  14.     Foreground="{StaticResource PhoneForegroundBrush}"
  15.     SupportedOrientations="Portrait" Orientation="Portrait"
  16.     shell:SystemTray.IsVisible="True">
  17.  
  18.     <phone:PhoneApplicationPage.Resources>
  19.  
  20.         <ControlTemplate x:Key="panoramaTemplate" TargetType="ctl:Panorama">
  21.             <Grid>
  22.                 <Grid.RowDefinitions>
  23.                     <RowDefinition Height="auto"/>
  24.                     <RowDefinition Height="*"/>
  25.                 </Grid.RowDefinitions>
  26.  
  27.                 <!-- The use of the margin on the Border will prevent rendering artifacts (dark vertical lines). -->
  28.                 <ctlp:PanningBackgroundLayer x:Name="BackgroundLayer" Grid.RowSpan="2" HorizontalAlignment="Left">
  29.                     <Border x:Name="background" Background="{TemplateBinding Background}" CacheMode="BitmapCache" Margin="-1,0"/>
  30.                 </ctlp:PanningBackgroundLayer>
  31.  
  32.                 <ctlp:PanningTitleLayer x:Name="TitleLayer" Grid.Row="0" HorizontalAlignment="Left" Margin="10,-76,0,9"
  33.                                                         Content="{TemplateBinding Title}" ContentTemplate="{TemplateBinding TitleTemplate}"
  34.                                                         FontSize="187" FontFamily="{StaticResource PhoneFontFamilyLight}" CacheMode="BitmapCache"/>
  35.  
  36.                 <ctlp:PanningLayer x:Name="ItemsLayer" Grid.Row="1" HorizontalAlignment="Left">
  37.                     <ItemsPresenter x:Name="items"/>
  38.                 </ctlp:PanningLayer>
  39.             </Grid>
  40.         </ControlTemplate>
  41.     </phone:PhoneApplicationPage.Resources>
  42.  
  43.     <Grid x:Name="LayoutRoot">
  44.         <ctl:Panorama Template="{StaticResource panoramaTemplate}" Title="background image">
  45.             <ctl:Panorama.Background>
  46.                 <ImageBrush ImageSource="BK.jpg"/>
  47.             </ctl:Panorama.Background>
  48.             <ctl:PanoramaItem Header="item 0"/>
  49.             <ctl:PanoramaItem Header="item 1"/>
  50.             <ctl:PanoramaItem Header="item 2"/>
  51.         </ctl:Panorama>
  52.     </Grid>
  53.  
  54. </phone:PhoneApplicationPage>

Notice the Margin added to the Border named “background” (line 29). That’s the only change in the Panorama template.

SeamlessPanorama.zip