views:

186

answers:

2

Hi there,

I want to create a custom scrollviewer control for a touch screen application without using scrollbars. To accomplish letting the users know that they can scroll the content, I am fading the bottom and top part of the scrollviewer with a linear gradient using an opacitymask. This all works fine, except for a problem with the opacitymask applying to the textblock in addition to the scrollviewer!

What I mean is, I would like the fading effect to apply to the top 1% and bottom 1% of the scrollviewer, and then the middle of the scrollviewer will be visible. The problem, however, is that this effect is also happening on the control within the scrollviewer as well, even if i set OpacityMask="{x:Null}" on the textblock.

I have tried applying the opacitymask to the outside of the scrollviewer as well but the same problem happens. Does the Opacitymask property apply to the children as well? Is there a better way to doing this fading effect?

Here is the code I am using:

<Grid Width="200" Height="130">
 <ScrollViewer BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="2"
                           HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden" >
  <ScrollViewer.OpacityMask>
   <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientStop Color="Transparent" Offset="0" />
                <GradientStop Color="Black" Offset="0.1" />
                <GradientStop Color="Black" Offset="0.9" />
                <GradientStop Color="Transparent" Offset="1" />
            </LinearGradientBrush>
  </ScrollViewer.OpacityMask>
  <TextBlock Margin="0,10" Style="{StaticResource textSmall}" TextWrapping="Wrap">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
  </TextBlock>
    </ScrollViewer>
</Grid>
+1  A: 

You could add a control with a transparent gradient on top of the ScrollViewer within the same Grid and set its 'IsHitTestVisible' to false to achieve this effect. Here is a modified version of your example using a Canvas control on top of the ScrollViewer:

<Grid Width="200" Height="130">
            <ScrollViewer BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="2"
                           HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden"  Background="LightBlue">
                <TextBlock Margin="10,30,10,30" TextWrapping="Wrap" OpacityMask="Black" VerticalAlignment="Center">
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
                </TextBlock>
            </ScrollViewer>
            <Canvas Width="200" Height="130" Focusable="False" IsEnabled="False" IsHitTestVisible="False">
                <Canvas.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                        <GradientStop Color="#FFFFFFFF" Offset="0" />
                        <GradientStop Color="#00FFFFFF" Offset="0.1" />
                        <GradientStop Color="#00FFFFFF" Offset="0.9" />
                        <GradientStop Color="#FFFFFFFF" Offset="1" />
                    </LinearGradientBrush>
                </Canvas.Background>
            </Canvas>
        </Grid>

I added a background color to the ScrollViewer and a large top margin to the TextBlock so that it would be easy to confirm the desired effect. Here is what the output looked like: alt text

Ben Collier
This is what I had before I started using OpacityMask. The reason I switched over to OpacityMask was because of a background image on the grid that would get the white box on top of it, which I don't want. I want it to be transparent instead, which OpacityMask achieves.
Willson Haw
Hmm, I'm not sure I understand. The gradient I am drawing is mostly transparent, just like the OpacityMask. Rather than go from white to black to white in the gradient, I go from white to transparent to white. It shouldn't cover the background image except with the faded white at the top and the bottom. If this is what you were trying to avoid, then I am once again stumped. :)
Ben Collier
Yeah, the faded white part is what is overlapping the image, which isn't what I want it to do. I really have no idea what I can do to get rid of that opacitymask on the textblock :(
Willson Haw
A: 

I faced the same problem today, and the solution is actually very simple: set the ScrollViewer.Background property to anything but null (in your case you'd want Transparent), and it works.

I'm posting the answer here as it's the only question I found regarding this problem.

Antoine B-J