locked
Animate Pan/Moving of HubSection

    Question

  • Hi,

    after a few days of searching in forums, I found an excellent code that animate the Pan/Moving of HubSection in Hub.

    TimeSpan period = TimeSpan.FromMilliseconds(100);
    Windows.System.Threading.ThreadPoolTimer.CreateTimer(async (source) =>
    {
         await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() =>
           {
                ScrollHubToSection(MainHub, MainHub.Sections[1]);
           }));
    }, period);
    

    but it works only when Hub has two HubSections, otherwise just nothing happens..

    Does anyone know, how can I animate Pan/Moving of HubSection when Hub has 3 or more Hubsections?

    Friday, February 20, 2015 9:09 AM

Answers

  • This is the code I currently use (a blog post is on its way). It's an extension method:

            public async static Task ScrollToSectionAnimated(this Hub hub, HubSection section)
            {
                // Find the internal scrollviewer and its current horizontal offset.
                var viewer = hub.GetFirstDescendantOfType<ScrollViewer>();
                var current = viewer.HorizontalOffset;
    
                // Find the distance to scroll.
                var visual = section.TransformToVisual(hub);
                var point = visual.TransformPoint(new Point(0, 0));
                var offset = point.X;
    
                // Scroll in a more or less animated way.
                var increment = offset / 24;
                for (int i = 1; i < 25; i++)
                {
                    viewer.ChangeView((i * increment) + current, null, null, true);
                    await Task.Delay(TimeSpan.FromMilliseconds(i));
                }
            }

    The call looks like this:

    await this.MainHub.ScrollToSectionAnimated(this.MainHub.Sections[1]);

    • Marked as answer by sharpXO Monday, February 23, 2015 10:25 AM
    Monday, February 23, 2015 9:31 AM

All replies

  • Most (if not all) of the ScrollHubToSection code samples that I encountered forget to add the current position of the ScrollViewer (viewer.HorizontalOffset). So they start scrolling from zero and always end up in the second HubSection. That code indeed only works fine in a two-section hub.

    The example here e.g. should have the following line:

    var offset = index*section.ActualWidth + viewer.HorizontalOffset;

    Monday, February 23, 2015 7:48 AM
  • Hi Diederik, thanks for your replay, now I change code following:

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
         await ScrollHubToSection(MainHub, MainHub.Sections[1], 1);
    }
    private async static Task ScrollHubToSection(Hub hub, HubSection section, int index)
    {
        var dispatcher = hub.Dispatcher;
        var viewer = Find.FindChild<ScrollViewer>(hub, "ScrollViewer");
        var offset = index * section.ActualWidth + viewer.HorizontalOffset;
        for (int i = 0; i < index; i++)
        {
            offset += hub.Sections[i].ActualWidth;
        }
        await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => viewer.ChangeView(offset, null, null, false));
    }
     

    But result the same... when the Hub has only 2 HubSections - the code works perfectly,

    but if I add a simple third HubSection, after button click, Hubsection stand at the same place (don't move).

    Output: A first chance exception of type 'System.ArgumentException' occurred in mscorlib.ni.dll

    Maybe I missed something?

    Monday, February 23, 2015 9:21 AM
  • This is the code I currently use (a blog post is on its way). It's an extension method:

            public async static Task ScrollToSectionAnimated(this Hub hub, HubSection section)
            {
                // Find the internal scrollviewer and its current horizontal offset.
                var viewer = hub.GetFirstDescendantOfType<ScrollViewer>();
                var current = viewer.HorizontalOffset;
    
                // Find the distance to scroll.
                var visual = section.TransformToVisual(hub);
                var point = visual.TransformPoint(new Point(0, 0));
                var offset = point.X;
    
                // Scroll in a more or less animated way.
                var increment = offset / 24;
                for (int i = 1; i < 25; i++)
                {
                    viewer.ChangeView((i * increment) + current, null, null, true);
                    await Task.Delay(TimeSpan.FromMilliseconds(i));
                }
            }

    The call looks like this:

    await this.MainHub.ScrollToSectionAnimated(this.MainHub.Sections[1]);

    • Marked as answer by sharpXO Monday, February 23, 2015 10:25 AM
    Monday, February 23, 2015 9:31 AM
  • Yes! wonderful, it works, Thank you very very much!
    Monday, February 23, 2015 10:25 AM