ScrollView position indicator

Is there a way I can display a scrollbar (position indicator) inside a scrollview? Like in iOS in the mail app.

The ScrollingAnimation trigger is bound to the position of the scrollview.

<ScrollingAnimation>
   <Move Target="ScrollbarBox" Y="1" RelativeTo="ParentSize"/>
</ScrollingAnimation>

This will move the target element from the top to the bottom of its parent to match the scrolling position.

You may also wish to look at the WhileScrollable trigger.

Yes! Should be easy to make in UX :slight_smile:

Have a look at this:

<App Theme="Basic" Background="#fff">
    <ClientPanel>
        <DockPanel>
            <Panel Height="45" Background="#0fc" Dock="Top">
                <Text Alignment="Center" FontSize="20">Some title</Text>
            </Panel>
            <Panel Dock="Fill">
                <Rectangle Width="8" Margin="2,0,2,0" CornerRadius="10" Alignment="Right" >
                    <SolidColor Color="#44444466" />
                </Rectangle>
                <Rectangle Height="5%" Width="8" Margin="2,0,2,0" CornerRadius="10" Alignment="TopRight" ux:Name="_scrollIndicator">
                    <SolidColor Color="#44444488" />
                </Rectangle>
                <ScrollView Background="#0ca" ux:Name="_scrollView">
                    <ScrollingAnimation>
                        <Move Y="0.95" RelativeNode="_scrollView" RelativeTo="Size" Target="_scrollIndicator" />
                    </ScrollingAnimation>
                    <StackPanel>
                        <Each Count="30">
                            <Rectangle Height="80" Margin="14">
                                <SolidColor Color="#eee" />
                            </Rectangle>
                        </Each>
                    </StackPanel>
                </ScrollView>
            </Panel>
        </DockPanel>
    </ClientPanel>
</App>

Tnx for the replies. Thats seems to work, however I’m trying to only show it during the scrolling progress.

I tried the following:

<Rectangle Opacity="0" Height="5%" Width="8" Margin="2,0,2,0" CornerRadius="10" Alignment="TopRight" ux:Name="_scrollIndicator">
    <SolidColor Color="#666666AA" />
</Rectangle>
<ScrollView SnapMinTransform="false" ux:Name="_scrollView">
    <ScrollingAnimation>
        <Move Y="0.95" RelativeNode="_scrollView" RelativeTo="Size" Target="_scrollIndicator" />
        <Change _scrollIndicator.Opacity="1" Duration="1" DurationBack="1" />
    </ScrollingAnimation>
    ...

And

<Rectangle Visibility="Hidden" Height="5%" Width="8" Margin="2,0,2,0" CornerRadius="10" Alignment="TopRight" ux:Name="_scrollIndicator">
    <SolidColor Color="#666666AA" />
</Rectangle>
<ScrollView SnapMinTransform="false" ux:Name="_scrollView">
    <ScrollingAnimation>
        <Move Y="0.95" RelativeNode="_scrollView" RelativeTo="Size" Target="_scrollIndicator" />
        <Change _scrollIndicator.Visibility="Visible" />
    </ScrollingAnimation>
    ...

However with both the indicator stays hidden

I just tried it with WhilePressed on the scrollview. It seems to work partially, but when I release my finger and the scroll animation continues the indicator fades out. This is ofcourse expected with the WhilePressed gesture, is there a similair one for the complete scrolling duration?

Also I just found out why my previous examples didn’t work. The new value is relative to the scrollposition (or something). If I can put a fixed value there the problem would also be fixed.

You can make it stay for like 3 more sec, the scrolling should be over.

We do not have a trigger that is active while the ScrollViewer is in motion, sounds like something we might need :wink: A for now you can work around it by using LimeInBox`s suggestion.

I wrote a simple WhileTrigger to show you how this could be done:

public class WhileScrolling : WhileTrigger
{

    ScrollView _scrollView;

    protected override void OnRooted(Node parentNode)
    {
        base.OnRooted(parentNode);
        if (parentNode is ScrollView)
        {
            _scrollView = (ScrollView)parentNode;
            _scrollView.ScrollPositionChanged += OnScrollPositionChanged;
        }
    }

    protected override void OnUnrooted(Node parentNode)
    {
        base.OnUnrooted(parentNode);
        if (_scrollView != null)
        {
            _scrollView.ScrollPositionChanged -= OnScrollPositionChanged;
            _scrollView = null;
        }
    }

    bool _isActive = false;
    int _prevFrameIndex = 0;

    void OnScrollPositionChanged(object sender, EventArgs args)
    {
        if (!_isActive)
        {
            _isActive = true;
            SetActive(true);
            UpdateManager.AddAction(OnUpdate);
        }
        _prevFrameIndex = UpdateManager.FrameIndex;
    }

    void OnUpdate()
    {
        if (_prevFrameIndex < UpdateManager.FrameIndex)
        {
            SetActive(false);
            _isActive = false;
            UpdateManager.RemoveAction(OnUpdate);
        }
    }

}

Tnx that works good enough for now :wink: changed it to a delayback of 5 seconds and most of the times the scrolling is done by the time it fades out.

@Vegard Strand Lende - Thanks!