The Windows Store ScrollViewer XAML has a bug. It causes a visual error on the screen when the ScrollViewer has no scroll bars.

I discovered this because I have a main page in my app that uses the Visual Studio provided framework for a tiled app. The main page uses a GridView and the GridView contains a ScrollViewer. I didn’t see the problem until I made another page that needed tile to match the main page, but could not use the GridView container. The GridView won’t handle variable height elements within it.

On my new page, I used a WrapPanel object that I talk about in this post. To get my tiles to act like buttons when they are pressed, I just created new tile controls that use a single GridView for each tile. This gives me the exact same button press visual change that I get on the main page, but I didn’t need to add any visual state handling to my new tile controls. It was a kludge and a shortcut, for sure.

Anyhow, a small dot appeared on the screen near the bottom right corner of these GridView wrapped tiles whenever the mouse moved over them. The dot never went away. I eventually tracked it down to being a small Border object that is supposed to separate the horizontal and vertical scrollbars where they meet.

image

The Dot

In the image above, the dot is that greyish dot just beyond the bottom right corner of the mostly transparent tile. here is a close-up:

image

The Dot – Close Up

My fix was to simply set the opacity of the Border to zero. Here is the entire ScrollViewer style XML with the one smal change:

    <Style TargetType="ScrollViewer">
        <Setter Property="HorizontalScrollMode" Value="Enabled" />
        <Setter Property="VerticalScrollMode" Value="Enabled" />
        <Setter Property="IsHorizontalRailEnabled" Value="True" />
        <Setter Property="IsVerticalRailEnabled" Value="True" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="ZoomMode" Value="Enabled" />
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Top"/>
        <Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ScrollViewer">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ScrollingIndicatorStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition From="MouseIndicator" To="NoIndicator">
                                        <Storyboard>
                                            <FadeOutThemeAnimation TargetName="ScrollBarSeparator" BeginTime="0:0:3" />
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="VerticalScrollBar"
                                                                       Storyboard.TargetProperty="IndicatorMode">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:3">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <ScrollingIndicatorMode>None</ScrollingIndicatorMode>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalScrollBar"
                                                                       Storyboard.TargetProperty="IndicatorMode">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:3">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <ScrollingIndicatorMode>None</ScrollingIndicatorMode>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualTransition>
                                    <VisualTransition From="TouchIndicator" To="NoIndicator">
                                        <Storyboard>
                                            <FadeOutThemeAnimation TargetName="ScrollBarSeparator" />
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="VerticalScrollBar"
                                                                       Storyboard.TargetProperty="IndicatorMode">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <ScrollingIndicatorMode>None</ScrollingIndicatorMode>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalScrollBar"
                                                                       Storyboard.TargetProperty="IndicatorMode">
                                                <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <ScrollingIndicatorMode>None</ScrollingIndicatorMode>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualTransition>
                                </VisualStateGroup.Transitions>

                                <VisualState x:Name="NoIndicator">
                                    <Storyboard>
                                        <FadeOutThemeAnimation TargetName="ScrollBarSeparator" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="TouchIndicator">
                                    <Storyboard>
                                        <FadeOutThemeAnimation TargetName="ScrollBarSeparator" />
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="VerticalScrollBar"
                                                                   Storyboard.TargetProperty="IndicatorMode"
                                                                   Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <ScrollingIndicatorMode>TouchIndicator</ScrollingIndicatorMode>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalScrollBar"
                                                                   Storyboard.TargetProperty="IndicatorMode"
                                                                   Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <ScrollingIndicatorMode>TouchIndicator</ScrollingIndicatorMode>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="MouseIndicator">
                                    <Storyboard>
                                        <FadeInThemeAnimation TargetName="ScrollBarSeparator" />
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="VerticalScrollBar"
                                                                   Storyboard.TargetProperty="IndicatorMode"
                                                                   Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <ScrollingIndicatorMode>MouseIndicator</ScrollingIndicatorMode>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalScrollBar"
                                                                   Storyboard.TargetProperty="IndicatorMode"
                                                                   Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <ScrollingIndicatorMode>MouseIndicator</ScrollingIndicatorMode>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid Background="{TemplateBinding Background}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <ScrollContentPresenter x:Name="ScrollContentPresenter"
                                                Grid.RowSpan="2"
                                                Grid.ColumnSpan="2"
                                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                                Margin="{TemplateBinding Padding}" />
                            <ScrollBar x:Name="VerticalScrollBar"
                                   Grid.Column="1"
                                   IsTabStop="False"
                                   Maximum="{TemplateBinding ScrollableHeight}"
                                   Orientation="Vertical"
                                   Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
                                   Value="{TemplateBinding VerticalOffset}"
                                   ViewportSize="{TemplateBinding ViewportHeight}"
                                   HorizontalAlignment="Right"/>
                            <ScrollBar x:Name="HorizontalScrollBar"
                                   IsTabStop="False"
                                   Maximum="{TemplateBinding ScrollableWidth}"
                                   Orientation="Horizontal"
                                   Grid.Row="1"
                                   Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
                                   Value="{TemplateBinding HorizontalOffset}"
                                   ViewportSize="{TemplateBinding ViewportWidth}" />
                            <!-- Change the opacity below, to zero. otherwise, the right and bottom border end up showing up as a single pixel lit on the screen even if the scroll is disabled. -->
                            <Border x:Name="ScrollBarSeparator"
                                Grid.Row="1"
                                Grid.Column="1"
                                Opacity="0"
                                BorderThickness="0,0,1,1"
                                Background="{StaticResource ScrollBarTrackBackgroundThemeBrush}"
                                BorderBrush="{StaticResource ScrollBarTrackBorderThemeBrush}" />
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

The change is at the bottom of all that XAML text.

Keep in mind that I did not try to determine how this affects the ScrollViewer in situations where the dot is somehow necessary. This Border thing in the corner doesn’t make sense anyhow, because scroll bars are not 1 unit wide. Why the border is there is beyond me. Why it is not hidden when both scroll bars are hidden is also beyond me. I think that it’s just a design mistake.