locked
Making the Windows 8 Hub Control Scroll Better - Programmatic Gestures RRS feed

  • Question

  • Question Can I improve the look and feel of a hub control when scrolling a specific section into view?
    How I am scrolling to a new section of a hub control HubMain.ScrollToSection(HubMain.Sections[2]);
    Problem It feels like it could be made more elegant. It would be nice if it had a gentle bounce action.
    Notes

    It works. But I’d rather see a bounce-like animation. Or a little slide action.

    I guess I can go up the inheritance tree to CONTROL and see if I can uncover an interface to scroll smoother.

    Question

    Is this possible?

    Can I setup some type of scrolling with animation?

    Can I programmatically send drag or slide gestures?


    Bruno Terkaly


    Friday, November 29, 2013 4:48 PM

Answers

  • Hi,

    ScrollToSection method implement by these steps:

    Firstly, get the scrollviewer which contain in Hub control.

    Then use UIElement.TransformToVisual method to scroll to the specific section. So the ScrollToSection do not have animation when go to section.

    You can get a scrollviewer which contain in Hub control. Then use ScrollViewer.ChangeView go to a sepecific hub section based on setting the horizontalOffset and verticalOffset. In the ScrollViewer.ChangeView you can set the

    disableAnimation to false that can enable zoom/pan animations while changing the view.

    Refer to the link:

    http://msdn.microsoft.com/en-US/library/windows/apps/dn252763

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by Anne Jing Monday, December 9, 2013 1:33 AM
    Monday, December 2, 2013 6:21 AM
  • Yes, that is the solution.

        private void ScollHubToSection(Hub hub, HubSection section)
        {
            var visual = section.TransformToVisual(this.MyHub);
            var point = visual.TransformPoint(new Point(0, 0));
            var viewer = Helpers.FindChild<ScrollViewer>(hub, "ScrollViewer");
            viewer.ChangeView(point.X, null, null);
        }


    Jerry Nixon

    • Marked as answer by Anne Jing Wednesday, December 4, 2013 12:59 AM
    • Unmarked as answer by Anne Jing Wednesday, December 4, 2013 5:27 AM
    • Marked as answer by Anne Jing Monday, December 9, 2013 1:34 AM
    Tuesday, December 3, 2013 11:13 PM

All replies

  • Hi,

    ScrollToSection method implement by these steps:

    Firstly, get the scrollviewer which contain in Hub control.

    Then use UIElement.TransformToVisual method to scroll to the specific section. So the ScrollToSection do not have animation when go to section.

    You can get a scrollviewer which contain in Hub control. Then use ScrollViewer.ChangeView go to a sepecific hub section based on setting the horizontalOffset and verticalOffset. In the ScrollViewer.ChangeView you can set the

    disableAnimation to false that can enable zoom/pan animations while changing the view.

    Refer to the link:

    http://msdn.microsoft.com/en-US/library/windows/apps/dn252763

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by Anne Jing Monday, December 9, 2013 1:33 AM
    Monday, December 2, 2013 6:21 AM
  • Getting the scroll viewer You mentioned I can get the scrollviewer. I cannot find it as part of the Hub Contro hierarchy.
    The hub control inheritance is Hub < Control < Framework Element < UIElement. Where is the scrollviewer? Is it the parent? I'm showing the Grid as the parent in my XAML code.
    How would you replace the code the right? HubMain.ScrollToSection(HubMain.Sections[2]);
    Let's say I want to scroll to 2.5, halfway to the 3rd section of the hub control.

    What would the code look like?

    I can't do this:

    HubMain.ScrollToSection(HubMain.Sections[2.5]);

    How would I use TransformToVisual? Can you create a File/New Project with a hub control and show me a snippet? Do you have any sample code?

    Your help is much appreciated.

    Bruno Terkaly


    Monday, December 2, 2013 7:25 AM
  • Hi,

    Scrollviewer contain in hub control style template:

    <Style x:Key="HubStyle1" TargetType="Hub">
                <Setter Property="HorizontalContentAlignment" Value="Left"/>
                <Setter Property="Padding" Value="40,60,40,0"/>
                <Setter Property="IsTabStop" Value="False"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Hub">
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="OrientationStates">
                                        <VisualState x:Name="Horizontal"/>
                                        <VisualState x:Name="Vertical">
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="HorizontalScrollMode" Storyboard.TargetName="ScrollViewer">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="Disabled"/>
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="HorizontalScrollBarVisibility" Storyboard.TargetName="ScrollViewer">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="Disabled"/>
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="VerticalScrollMode" Storyboard.TargetName="ScrollViewer">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="Auto"/>
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="VerticalScrollBarVisibility" Storyboard.TargetName="ScrollViewer">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="Auto"/>
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="ScrollViewer">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.RowSpan)" Storyboard.TargetName="ScrollViewer">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Storyboard.TargetName="ScrollViewer">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="0,20,0,0"/>
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto"/>
                                        <RowDefinition Height="*"/>
                                    </Grid.RowDefinitions>
                                    <ScrollViewer x:Name="ScrollViewer" HorizontalScrollMode="Auto" HorizontalSnapPointsAlignment="Near" HorizontalSnapPointsType="Optional" HorizontalScrollBarVisibility="Auto" Grid.RowSpan="2" VerticalSnapPointsType="Optional" VerticalScrollBarVisibility="Disabled" VerticalScrollMode="Disabled" VerticalSnapPointsAlignment="Near" ZoomMode="Disabled">
                                        <ItemsStackPanel x:Name="Panel" CacheLength="20" Orientation="{TemplateBinding Orientation}"/>
                                    </ScrollViewer>
                                    <Border x:Name="HeaderHost" Padding="{TemplateBinding Padding}" Grid.Row="0">
                                        <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" FontWeight="{ThemeResource HubHeaderThemeFontWeight}" FontSize="{ThemeResource HubHeaderThemeFontSize}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" OpticalMarginAlignment="TrimSideBearings" TextLineBounds="Tight"/>
                                    </Border>
                                </Grid>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

    You can use VisualTreeHelper API to find the scrollviewer which contain in hub control.

    And you cannnot use "HubMain.ScrollToSection(HubMain.Sections[2.5])“the method parameter is specific hub section.

    I recommend you can use  ScrollViewer.ChangeView go to a specific hub section. But you should caculate the horizontalOffset and verticalOffset between hub sections.

    The ScrollToSection mehod do not have animation when you use it to make sepcific hub section into view. I do not recommend you use TransformToVisual method. I only describe how to implement ScrollToSection and clarify the ScrollToSection do not have animation when you use it.

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by Anne Jing Wednesday, December 4, 2013 12:59 AM
    • Unmarked as answer by Anne Jing Wednesday, December 4, 2013 5:28 AM
    Monday, December 2, 2013 8:14 AM
  • Yes, that is the solution.

        private void ScollHubToSection(Hub hub, HubSection section)
        {
            var visual = section.TransformToVisual(this.MyHub);
            var point = visual.TransformPoint(new Point(0, 0));
            var viewer = Helpers.FindChild<ScrollViewer>(hub, "ScrollViewer");
            viewer.ChangeView(point.X, null, null);
        }


    Jerry Nixon

    • Marked as answer by Anne Jing Wednesday, December 4, 2013 12:59 AM
    • Unmarked as answer by Anne Jing Wednesday, December 4, 2013 5:27 AM
    • Marked as answer by Anne Jing Monday, December 9, 2013 1:34 AM
    Tuesday, December 3, 2013 11:13 PM
  • I've added the code here so you can run it for yourself.

    http://sdrv.ms/1bgrGTb

    Thanks Thanks Anne and Thanks Jerry. Jerry you gave me exactly what I needed. Kind of.
    Why I am not 100% satisfied with the result I'm trying to show the gradual panning to the third hub. So I've added a loop with waiting as seen below. But it doesn't feel right. If change the wait time, it still executes the same way (probably because of something async)
    It works, but... Is this the most elegant code to do the gradual panning? Doesn't feel right.



    Scroll Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    async private void ScrollHubToSection(Hub hub, HubSection section)
    {
        var visual = section.TransformToVisual(hub);
        var viewer = UIHelper.FindChild<ScrollViewer>(hub, "ScrollViewer");
        for (int i = 0; i < 14; i++)
        {
            await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                var point = visual.TransformPoint(new Point(-5, 0));
                viewer.ChangeView(point.X, nullnull);
                Task.Delay(TimeSpan.FromMilliseconds(400));
            });
        }
    }

    Bruno Terkaly





    Wednesday, December 4, 2013 5:04 AM
  • Hi,

    For now, this is the most elegant code to do the gradual panning in windows store app.

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Monday, December 9, 2013 1:33 AM
  • Hi Bruno,

    I suppose you can remove that loop when you edit the Hubs template and replace the ItemsStackPanel contained by a simple StackPanel.

    I don´t know what performance issues this maybe creates but it worked for me and as long as there are only a few sections it wont be that bad, does it?

    Christoph Wieske

    PS: Sorry for the late response. Hope that makes it a little more elegant...

    Saturday, August 23, 2014 9:56 PM
  • Hi Bruno

    async private void ScrollHubToSection(Hub hub, HubSection section)
    {
        var visual = section.TransformToVisual(hub);
        var viewer = UIHelper.FindChild<ScrollViewer>(hub, "ScrollViewer");
        for (int i = 0; i < 14; i++)
        {
            await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                var point = visual.TransformPoint(new Point(-5, 0));
                viewer.ChangeView(point.X, null, null);
                Task.Delay(TimeSpan.FromMilliseconds(400));
            });
        }
    }

    I tried this code to wp 8.1
    It does not work if the number of HubSection > 2 why?

    If two runs, if not three runs.

    • Edited by Ex Mi Wednesday, September 24, 2014 12:46 PM
    Wednesday, September 24, 2014 12:45 PM
  • Same issue here. I have a Hub with 3 sections. Won't do the scrolling magic unfortunately.

    Wednesday, November 5, 2014 11:08 AM