Keep element in view while scrolling

天大地大妈咪最大 提交于 2019-12-24 13:44:08

问题


Simpel question, I have a windows phone page that contains a scrollviewer with inside it an image, a textblock and a richtextbox.

Now when the user starts scrolling I want to keep the textblock in view on top when the image has scrolled outside the page.

So the effect is, user starts scrolling upwards, everything scrolls upwards, when the image is outside the page, the textblock stays at the top of the page but the richtextbox keeps scrolling upwards.

Any thoughts?


回答1:


Here is a way to reach this result:

First, the layout. I've set a grid, with two rows. The first is empty, and will host the header when we need to freeze it. The second row contains the scrollviewer.

Inside the scrollviewer, I've put the controls in a grid, but you can use whatever container suits you.

<ScrollViewer Grid.Row="1"
                Margin="0"
                Padding="0"
                x:Name="ParentScroll"
                ManipulationMode="Control"
                MouseMove="ParentScroll_MouseMove">
    <Grid x:Name="ChildGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Image Source="Picture.jpg" Grid.Row="0"/>
        <TextBlock Text="Header" Grid.Row="1" x:Name="TextHeader" />
        <RichTextBox Grid.Row="2" x:Name="RichText">
            <Paragraph>
                <Bold>RichTextBox</Bold>
                <!-- More stuff -->
            </Paragraph>
        </RichTextBox>
    </Grid>
</ScrollViewer>

I use the MouseMove event to be notified of the scrolling event. You can also dig into the template, extract the ScrollBar control, and subscribe to the ValueChanged event, as described here: http://social.msdn.microsoft.com/Forums/wpapps/en-US/81fcd34e-6ec9-48d0-891e-c53a53344553/scrollviewer-synchronization

Note that you need to set ManipulationMode to Control or the position of the controls won't be updated at a smooth rate. I guess it's due to some internal optimization.

In the code behind, I use the TransformToVisual method to compute the relative position of the controls to the ScrollViewer. This way, I can know when the header goes out of view. When it does, I remove it from the child grid, and put it outside of the ScrollViewer, in the parent grid. When the top of the RichTextBox goes out of view, I put the header back into the ScrollViewer:

private void ParentScroll_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
    if (Grid.GetRow(this.TextHeader) == 1)
    {
        var generalTransform = TextHeader.TransformToVisual(ParentScroll);
        var childToParentCoordinates = generalTransform.Transform(new Point(0, 0));

        if (childToParentCoordinates.Y < 0)
        {
            this.ChildGrid.Children.Remove(this.TextHeader);
            this.ParentGrid.Children.Add(this.TextHeader);

            Grid.SetRow(this.TextHeader, 0);
        }
    }
    else
    {
        var generalTransform = RichText.TransformToVisual(ParentScroll);
        var childToParentCoordinates = generalTransform.Transform(new Point(0, 0));

        if (childToParentCoordinates.Y > 0)
        {
            this.ParentGrid.Children.Remove(this.TextHeader);
            this.ChildGrid.Children.Add(this.TextHeader);

            Grid.SetRow(this.TextHeader, 1);
        }
    }

There may be less-hacky ways to reach the same results, but this solution seems to work smoothly in the emulator.




回答2:


I've found a working solution myself... the complete detail is available on my blog here... it contains also the link to my demo project on GitHub.

The trick was to get hold of the VerticallScrollBar inside the ScrollViewer and to set the ManipulationMode to Control to get enough feedback on the UI thread. With the scroll offset information of the scrollbar we than animate the specific ui element we want to keep in view.



来源:https://stackoverflow.com/questions/18424301/keep-element-in-view-while-scrolling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!