Page Transitions

Dec 13, 2014 at 3:44 PM
Good afternoon.

I started using this solution over WinRT XAML Toolkit's because of the page caching problem, which you have fixed and that's fine.

However, this implementation of page transitions is not as evolved as in that other package, since here I ALWAYS see a black screen between the two animations (from and to), i.e., they seem to be performed in order and therefore the two steps are separated. In WinRT XAML Toolkit, for example using the PushPageAnimation (the one I prefer over all the other ones), the animation is much more pleasant, because the user sees not a black page pushing the current page off, but the NEW page, which is way cooler and user-friendly, and I had implemented that in all of my apps.

The caching solution is very important for me and I'll even talk about it as a great feature in my next releases, but I really didn't want to loose the smooth page transitions that I had before.

Can you please fix this?

Thank you.
Coordinator
Dec 13, 2014 at 4:24 PM
Hi,
Thanks for using the library.

Currently the navigation works as follows:
  1. Run out animation
  2. Load new page (black screen)
  3. Run in animation
I think you need this mode:
  1. Load new page (may introduce a lag/delay when clicking on a button)
  2. Run out animation
  3. Run in animation
Can you provide a sample where this black screen is reproduced?
Dec 13, 2014 at 4:29 PM
Good afternoon.

I appreciate the quick response.

You can reproduce this "issue" right in the source code's sample Windows 8.1 app: just provide a PageAnimation to the MtFrame (right now it seems that only TurnstilePageAnimation is supported), and you can see both animations being divided by a black screen (I just tried it because I downloaded the source code to play around with it a little bit, but I couldn't come up with anything).

Thank you.
Coordinator
Dec 13, 2014 at 5:47 PM
And PushPageAnimation is a horizontal movement to the next page? Like on an iphone?
Dec 13, 2014 at 6:08 PM
Good afternoon.

To be honest with you what the animation is doesn't matter, does it? I mean, I can create new ones as I please (from and to), the black transition will always be there. Actually one of the problems is the black color too: in my case white would be better or at least some kind of transition image, but I understand that maybe that's how the Control class is implemented and you cannot customize that.

Yeah, I have managed to replicate WinRT XAML Toolkit's PushPageAnimation in MyToolkit for .NET: basically the current page slides out and the next page slides in (by playing with the margin of the page), using a random orientation (horizontal or vertical) and I also reverse the animation if the navigation is backwards (I don't know how an iPhone menu works).

Thank you.
Coordinator
Dec 13, 2014 at 6:12 PM
Yes, currently you can animate the first page then the second one is loaded (black screen) then the second screen is animated...

My idea is to first load the second page (issue: Small delay after button click and start of animation) then play the from animation (can animate both pages) then the to animation (also using both pages). This way everything is possible... Yes?
Dec 13, 2014 at 6:21 PM
Good afternoon.

Well, I understand what you mean (it makes totally sense and the code confirms that it is developed that way) and when you first told me that I went to the source code and changed the method NavigateInternal of the class MtFrame. Instead of setting the Content of the MtFrame I would save the page (which I believe is created here: newPage.GetPage(this).InternalPage;) to a variable and only set the Content AFTER performing CallOnNavigatedFrom and CallOnNavigatedTo.

But still nothing.

Can you help me out?

Thank you.
Coordinator
Dec 13, 2014 at 6:30 PM
It will not be that simple because currently only one page can be visible (the one set in the content property) but for your "advanced" animation to work both pages must be visible at the same... I will look into it tomorrow...
Dec 14, 2014 at 1:03 AM
Good evening.

I have managed to fix the issue with the tips of your last comment.

To summarize:

1 - Instead of the page itself, the Content of the MtFrame is now a Grid (that can hold multiple controls), as rsuter said;
2 - I keep both the previous page and the current page in the Grid ONLY until both animations are complete, THEN I remove the previous page;
3 - Another trick was to NOT await for the animation of the previous page to complete AND DO AWAIT for the animation of the current page (this I believe was the complete opposite of the source code), although this was specifically made for MY desired effect of the new page to push the previous page, and so both animations must run at the same time;
4 - I did the aforementioned changes both in NavigateInternal and GoForwardOrBack methods of MtFrame.

I don't know if this is an optimal solution or if it has any downsides, but at the present time it works okay for me. I will reply to the thread if I find any problems with this approach, but I expect you to further test this scenario if you go ahead with it.

I will use this custom solution in my current app, but I believe that you should include it in the main package, either as the default behavior of any page transition or then create overloaded methods or aditional classes for those who need it. Furthermore I really wanted to keep using this solution within NuGet, so I will keep checking your updates to see when you deploy this.

Thank you VERY MUCH for pointing me the right way rsuter.
Coordinator
Dec 14, 2014 at 1:09 AM
Using a grid was also my tought, but everyting has to be tested with the new solution... Can you provide me your changes so that i can check it and use it?
Dec 14, 2014 at 1:25 AM
Good evening.

Of course, here are my changes (updated versions of methods in MtFrame and MtPage):
private async void GoForwardOrBack(NavigationMode mode)
{
    if (mode == NavigationMode.Forward ? CanGoForward : CanGoBack)
    {
        var oldPage = CurrentPage;
        _currentIndex += mode == NavigationMode.Forward ? 1 : -1;
        var newPage = CurrentPage;

        if (mode == NavigationMode.Back && DisableForwardStack)
            RemoveForwardStack();

        var activatedPage = newPage.GetPage(this).InternalPage;
        var grid = new Grid();

        if (Content is Grid)
        {
            grid = Content as Grid;
            grid.Children.Add(activatedPage);
        }
        else
        {
            grid.Children.Add(activatedPage);
        }

        Content = grid;

        CallOnNavigatedFrom(oldPage, mode);
        await CallOnNavigatedTo(newPage, mode);

        if (grid.Children.Count > 1)
        {
            grid.Children.RemoveAt(0);
        }

        ((RelayCommand)GoBackCommand).RaiseCanExecuteChanged();
    }
    else
        throw new Exception("cannot go forward or back");
}

private async void NavigateInternal(Type type, object parameter)
{
    // Remove forward stack
    var previousPage = CurrentPage;
    RemoveForwardStack();

    // Create new page
    var newPage = new MtPageDescription(type, parameter);
    _pages.Add(newPage);
    _currentIndex++;

    var activatedPage = newPage.GetPage(this).InternalPage;
    var grid = new Grid();

    if (Content is Grid)
    {
        grid = Content as Grid;
        grid.Children.Add(activatedPage);
    }
    else
    {
        grid.Children.Add(activatedPage);
    }

    Content = grid;

    // Call navigation event methods
    if (previousPage != null)
    {
        CallOnNavigatedFrom(previousPage, NavigationMode.New);
    }

    await CallOnNavigatedTo(newPage, NavigationMode.New);

    if (grid.Children.Count > 1)
    {
        grid.Children.RemoveAt(0);
    }

    ((RelayCommand)GoBackCommand).RaiseCanExecuteChanged();

    // Destroy current page if cache is disabled
    if (previousPage != null && (previousPage.Page.NavigationCacheMode == NavigationCacheMode.Disabled || DisableCache))
        previousPage.Page = null;
}

private async Task<bool> CallOnNavigatingFromAsync(MtPageDescription description, NavigationMode mode)
{
    var page = description.GetPage(this);
    var args = new MtNavigatingCancelEventArgs();
    args.Content = page;
    args.SourcePageType = description.Type;
    args.NavigationMode = mode;

    IsNavigating = true;
    page.InternalOnNavigatingFromAsync(args);
    IsNavigating = false;

    return args.Cancel;
}

private async Task CallOnNavigatedTo(MtPageDescription description, NavigationMode mode)
{
    var page = description.GetPage(this);
    var args = new MtNavigationEventArgs();
    args.Content = page;
    args.SourcePageType = description.Type;
    args.Parameter = description.Parameter;
    args.NavigationMode = mode;
    await page.InternalOnNavigatedTo(args);

    var copy = Navigated;
    if (copy != null)
        copy(this, args);

    OnNavigated(this, args);

    if (args.NavigationMode == NavigationMode.New)
        OnPageCreated(this, page);
}

internal async virtual Task InternalOnNavigatedTo(MtNavigationEventArgs e)
{
    OnNavigatedTo(e);
    PageStateHandler.OnNavigatedTo(e);

    await AnimateNavigatedToAsync(e);
}
There are several scenarios of navigation in your Paging classes, so probably some of them are not handled by these changes. My tests were basically to navigate forward, navigate backwards and then confirm that the whole cache issue is still fixed after all of this (the reason I started using this package in the first place), and it is.

If you need anything else (for example the animation), don't hesitate to ask.

Thank you.
Coordinator
Dec 14, 2014 at 3:27 PM
I've updated all classes and added a sample animation PushPageAnimation, can you download the latest source code and test using your implementation?
Coordinator
Dec 15, 2014 at 6:16 PM
Ok, I've extended the IPageAnmiation interface, so that it is much more extensible and your requirements can be implemented..
Dec 15, 2014 at 6:58 PM
Good evening.

I have downloaded the new source code and sure enough the new animation architecture doesn't have a black screen in the middle, so congratulations and I believe that everyone will benefit from that.

Look, you don't have to keep editing the code just to please me, as the creator of this package you have to think if it makes sense for everyone. Since you're being so cool about it, I have some questions / suggestions:

1 - What is PageInsertionMode? (and the three values it has)
2 - Your implementation of the PushPageAnimation seems to be only horizontal and always in the same direction (> for forward and < for backwards). My implementation of this animation (and again, this is how I am making my app), is both horizontal and vertical and it's always random what is the animated axis and the direction too. But the way it is right now it's already a great second choice for animations! (you should add even more)
3 - One thing that I made in your code and it's very useful is to make the return value of the method InitializeFrameAsync the actual Frame, so that I can store and access it right from my App.cs. I also added a second parameter to include the animation I want for that frame instead of doing that in a particular page...

I will keep using my code until these things are fixed, but I understand if they aren't because these are just things that I thought better for myself and my apps...

Thank you.
Coordinator
Dec 15, 2014 at 7:09 PM
Edited Dec 15, 2014 at 7:11 PM
  1. It defines how the two (previous and next) pages are added to the grid => At the same time (concurrent) and prev on top of next or next on top of prev, or sequential (like the first paging implementation)
  2. I implemented PushPageAnimation only to test the implementation, if you have a better solution please provide the implementation
  3. You should overwrite OnInitializedAsync to initialize the frame as there are various scenarios where the frame is created (launched, file opened, etc.), see https://mytoolkit.codeplex.com/SourceControl/latest#SampleWindowsStoreApp/App.xaml.cs
Coordinator
Dec 15, 2014 at 7:17 PM
You need different animations per page? I'm thinking about adding a PageAnimation property to MtPage which overrides the one in MtFrame...
Dec 15, 2014 at 7:30 PM
Good evening.

1 - Okay, that's cool that there are so many options
2 - Yeah, I can give out my solution, here it is:
public class PushPageAnimation : IPageAnimation
{
    private static int _lastFromAnimation;
    private static int _lastToAnimation;

    public Task NavigatedToForward(FrameworkElement source)
    {
        if (_lastFromAnimation == 0)
        {
            var random = new Random();

            _lastToAnimation = random.Next(1, 5);

            return Push(source, _lastToAnimation, TransitionType.In);
        }

        return Push(source, _lastFromAnimation, TransitionType.In);
    }

    public Task NavigatedToBackward(FrameworkElement source)
    {
        if (_lastFromAnimation == 0)
        {
            var random = new Random();

            _lastToAnimation = random.Next(1, 5);

            return Push(source, _lastToAnimation, TransitionType.In);
        }

        return Push(source, _lastFromAnimation, TransitionType.In);
    }

    public Task NavigatingFromForward(FrameworkElement source)
    {
        var random = new Random();

        _lastFromAnimation = random.Next(1, 5);

        return Push(source, _lastFromAnimation, TransitionType.Out);
    }

    public Task NavigatingFromBackward(FrameworkElement source)
    {
        var random = new Random();

        _lastFromAnimation = random.Next(1, 5);

        return Push(source, _lastFromAnimation, TransitionType.Out);
    }

    private static Task Push(UIElement source, int type, TransitionType transitionType)
    {
        if (source == null)
        {
            return Task.FromResult<object>(null);
        }

        source.RenderTransform = new CompositeTransform();

        var duration = TimeSpan.FromSeconds(0.25);
        var story = new Storyboard();
        var pushAnimation = new DoubleAnimation();

        switch (type)
        {
            case 1:
                pushAnimation = new DoubleAnimation
                {
                    Duration = duration,
                    From = transitionType == TransitionType.In ? Window.Current.Bounds.Height : 0,
                    To = transitionType == TransitionType.In ? 0 : -Window.Current.Bounds.Height,
                };
                break;
            case 2:
                pushAnimation = new DoubleAnimation
                {
                    Duration = duration,
                    From = transitionType == TransitionType.In ? -Window.Current.Bounds.Height : 0,
                    To = transitionType == TransitionType.In ? 0 : Window.Current.Bounds.Height,
                };
                break;
            case 3:
                pushAnimation = new DoubleAnimation
                {
                    Duration = duration,
                    From = transitionType == TransitionType.In ? -Window.Current.Bounds.Width : 0,
                    To = transitionType == TransitionType.In ? 0 : Window.Current.Bounds.Width,
                };
                break;
            case 4:
                pushAnimation = new DoubleAnimation
                {
                    Duration = duration,
                    From = transitionType == TransitionType.In ? Window.Current.Bounds.Width : 0,
                    To = transitionType == TransitionType.In ? 0 : -Window.Current.Bounds.Width,
                };
                break;
        }

        switch (type)
        {
            case 1:
            case 2:
                Storyboard.SetTargetProperty(pushAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)");
                break;
            case 3:
            case 4:
                Storyboard.SetTargetProperty(pushAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
                break;
        }

        Storyboard.SetTarget(pushAnimation, source);

        story.Children.Add(pushAnimation);

        var completion = new TaskCompletionSource<object>();

        story.Completed += delegate
        {
            //source.RenderTransform = new CompositeTransform();

            completion.SetResult(null);
        };

        story.Begin();

        return completion.Task;
    }

    private enum TransitionType
    {
        In,
        Out
    }
}
3 - So, OnInitializedAsync is called no matter what was the type of app startup? (launched, file opened, etc.) If that's the case, then I'll use that method instead of OnLaunched, since I want to handle all types of scenarios
4 - Well, at the moment I don't need different animations per page (at least very different from each other, I think that's a little extreme), but I think that the possibility of doing that is VERY interesting, so I welcome you to do it...

Thank you.
Coordinator
Dec 15, 2014 at 7:42 PM
  1. Thanks
  2. No its not automatically called, but you should call await InitializeFrameAsync(args.PreviousExecutionState); in each overload, this always calls OnInitializedAsync when a new frame is created. See https://mytoolkit.codeplex.com/SourceControl/latest#SampleWindowsStoreApp/App.xaml.cs
  3. Ill add this but im not in a hurry and this feature will not introduce breaking changes
Coordinator
Dec 16, 2014 at 4:38 PM
Ok, now the MtPage class also provides a PageAnimation property...
Coordinator
Dec 19, 2014 at 9:56 PM
FYI: I just released v2.3.22 with all these improvements...
Dec 19, 2014 at 11:32 PM
Good evening.

2 - Thanks for the tip, I have done that in my current app.

I have included the latest version of the package but the way you have implemented the new version of IPageAnimation, I couldn't reproduce a smooth user experience due to the following reasons:

1 - If I include half of the animation in the "from" event and the other half in the "to" event (as you do in the source code), I can see a split second pause between both animations, which leads almost to the same old problem (and I can't have that in my apps).
2 - If I do all the animation at once in one of the events (either "from" or "to"), then I get the black screen again.

I really need the animation to run "at once" without any slowdown in one sequence, so for the time being I'm keeping my code.

Thank you.
Coordinator
Dec 19, 2014 at 11:36 PM
If you set UseBitmapCache to true the animations are much smoother.. Maybe this helps
Coordinator
Dec 19, 2014 at 11:40 PM
If you put the whole animation in the onnavigatingfrom method and ise a concurrent mode there should not be a black screen...
Dec 26, 2014 at 2:48 PM
Edited Dec 26, 2014 at 2:49 PM
Good afternoon.

Sorry for the waiting but I was more focused finishing the content of the app itself rather than to fine-tune this architectural feature. Here are my news:

1 - I have made as you said in the last comment (only using the "from" navigation event and using a concurrent mode) and you were correct: I got basically the same experience than my previous code, so from now on I'll be using your official package.
2 - If you can, please return the MtFrame when using the method InitializeFrameAsync and allow me to set the page animation in the same method signature (I don't think it'll break anything). Because if not, I have to perform not one but but the following four codes of line to get the same result:
await InitializeFrameAsync(args.PreviousExecutionState);

_currentFrame = Window.Current.Content as MtFrame;

if (_currentFrame != null)
{
    _currentFrame.PageAnimation = new PushPageAnimation();
}
3 - Here is another issue that I believe is not related to this package per se but I am asking for your help nevertheless. I started using this package because of the navigation caching feature, i.e., allowing me to return to a previously visited page without wasting more resources (beforehand all content had to be loaded again). However, this caching feature is "breaking / ruining" the language change of my app, i.e., if I change the language of my app in the settings (of the app), a cached instance of a page will NEVER EVER have the new language anymore. How can I force the page to update just the resources (and not the content itself)? And if that's not possible, how can I force a cached page to reload again (or to delete the cached version)? I consider this second possibility because my current app only has one cached page possible, due to the navigation combinations that it has, so it's not a big deal for me to completely reload that page, although I will have that issue for other more complex apps of mine, so ultimately the solution of just updating resources (the first one) would be MUCH BETTER.

Thank you.
Coordinator
Dec 26, 2014 at 3:50 PM
  1. Why don't you override OnInitializedAsync and put your animation creation logic there? This method is always called when a new frame is created and when the animation has to be initialized...
  2. We can extend the framework so that you can mark a page that it is removed from the cache and recreated. This way you can remove all pages from the cache after changing the language... Maybe there is a way to updated all resource bindings (maybe with DynamicResource intead of StaticResource?)
Dec 27, 2014 at 12:17 PM
Good afternoon.

1 - Thanks for the tip, it works very well.
2 - Localization in an WinRT app is made not using static or dynamic resources (as far as I know) but rather applying an Uid to the control and then having that matched to our localized resource files, so that second technique cannot be applied. Your extension suggestion may work very well, so I will wait for that in a next release and apply that to my apps as well (for now I am asking for people to restart the app and that's not so bad for the time being).

Thank you.
Jan 8, 2015 at 11:11 PM
Good evening.

I have yet another suggestion.

Can you please add another overload to InitializeFrameAsync that lets us NOT open the first page (or the default page), or at least lets us change the type of page opened first? There are at least two scenarios where my apps need to go to other pages: clicking a secondary tile and clicking an application link.

Thank you.
Jan 10, 2015 at 6:23 PM
Good afternoon.

So, I have been trying to address the requirement that I talked about in my last comment, and I have been able to successfully change the StartPageType attribute and thus change the type of startup page (i.e. this works). However, I found a scenario that broke what I wanted to achieve and I ended up changing this project's source code once again. This is the scenario:

1 - Start the app by clicking a secondary tile: everything works out as expected
2 - Start debugging my app (using VS2013)
3 - The app would open in the same page type previously used for the secondary tile startup (and not the default startup page type, even though the StartPageType was set to the correct page type)

The cause for this behavior was the following line of code, which would retrieve the previous page and load it again (inside InitializeFrameAsync):
await MtSuspensionManager.RestoreAsync();
When I commented this line, the page type started to be respected again.

Can you tell me what are the consequences for this? (the deleted line is only used in that method)

Thank you.
Coordinator
Jan 11, 2015 at 9:43 PM
This line is needed so that resuming an app works correctly (happens very rarely)...

I think you should always create the landing page and then depending on the app activation (eg secondary tile click) directly add another page on top of the landing page... There is only one instance of the app running and if the app is starting the app with the primary tile, then you need this landing page which would not be available in your proposed solution. This is why I think the StartPageType should be static and not changed depending on the activation...
Jan 12, 2015 at 9:07 PM
Good evening.

Well, I have been studying how the suspension works in WinRT (I never really paid much attention to it until now) and to be honest I believe that my apps do not greatly benefit from it.

To start off, pretty much all of the pages of my apps have predefined input parameters, so to benefit from suspension, I would have to save those variables prior to suspension so that I could retrieve them afterwards (and that would represent more hassle for me). Furthermore, I don't have corporate apps with long forms that I could resume / recover in case the app was suspended, nor my apps have really huge navigation flows that users can't get to the same page that they were before with extreme ease and speed. Plus, the only type of ApplicationExecutionState that calls RestoreAsync is Terminated, which means that the OS closed the app due to lack of system resources: as you say, something which probably rarely happens.

Due to the aforementioned reasons, I stand my position of avoiding that code. Can you please provide an overload to InitializeFrameAsync that let's us NOT use SuspensionManager?

Regarding the dynamic nature of the StartPageType, I will also maintain my current approach, since I don't want ANY page to exist between the start of the app and the targeted secondary tile page.

Thank you.
Coordinator
Jan 15, 2015 at 4:30 PM
I think one certification requirement is that suspend and resume works as expected, even if it happens rarely.. This is why i think disabling it is not a good idea and one main goal of this library is to support (and maybe force) the implementation of high quality apps... You can of course implement your own application class and use the rest - this way you have full flexibility... The docu also shows a way to use MtFrame without a MtApplication...
Coordinator
Jan 15, 2015 at 4:41 PM
And btw: If you would have implemented the app the usual way (without MyToolkit) you would have to save all state (all input boxes, scroll bars, etc.) when leaving the page so that they are restored, not only for suspending and resuming... In my opinion, you now only have to store the most important state (eg input boxes but not scroll bar locations) because suspension is very rare...
Jan 15, 2015 at 6:42 PM
Edited Jan 15, 2015 at 6:43 PM
Good evening.

1 - Technically I don't think that commenting that line has any effect on certification since I have just certified one of the apps that has the custom implementation of MyToolkit. Suspension is added using custom Visual Studio files, so I believe it is not enforced; as you probably know, we can even use blank templates without any files whatsoever for making an app.
2 - Please keep in mind that I WANT to use all your features, we're just talking about one line of code, so I will keep using MtApplication, MtFrame and MtPages throughout all my apps. As you said, the suspension issue / debate is not about MyToolkit (I know you're only following the guidelines), but rather about general WinRT development.
3 - I respect your opinion about using suspension meaning a high-quality app, but I do not agree with you. Obviously I do not agree with the opposite too, but I believe that each developer knows what is the best for their apps and they should opt in or out of suspension. For me, because my apps have the properties that I have explained earlier, I believe that suspension is not required at all.

Again, if you don't include the InitializeFrameAsync overload I will continue using your package in the same way, but I would appreciate it, since more people may feel the way I do. To summarize: disabling suspension allows me to enforce a consistent navigation pattern in all app startups without bothering with the extra effort of saving page states in all of my pages, something which may not be required according to the nature of the app.

Thank you.
Coordinator
Jan 15, 2015 at 7:00 PM
Ok, I've moved the code to two new methods:
        /// <summary>Restores the saved page states using the <see cref="MtSuspensionManager"/>. </summary>
        /// <returns>The task. </returns>
        protected virtual async Task RestoreStateAsync()
        {
            try
            {
                await MtSuspensionManager.RestoreAsync();
            }
            catch
            {
            }
        }

        /// <summary>Loads the saved page states using the <see cref="MtSuspensionManager"/>. </summary>
        /// <returns>The task. </returns>
        protected virtual async Task SaveStateAsync()
        {
            await MtSuspensionManager.SaveAsync();
        }
You can now override these two and return an empty/finished task so that the MtSuspensionManager methods are not called... This way it's possible to disable suspension/restore. However, I absolutely do not recommend this.
Coordinator
Jan 15, 2015 at 7:00 PM
Is this ok for you?
Jan 15, 2015 at 7:54 PM
Good evening.

Yes, I downloaded the latest source code, built your project, added the override and replaced the binaries and everything works just like before, so I really appreciate your help: this way MyToolkit continues to be directly usable for everyone, including me. :)

I will wait for the official release and then nuget added it to my apps.

By the way, are you also responsible for the WrapPanel? I have created another discussion over there but no one has responded yet...

Thank you.
Jan 21, 2015 at 7:43 PM
Good evening.

There seems to be a problem with my apps and I'm asking for your help in case it has anything to do with MyToolkit or otherwise you know what's going on generally speaking. I think it has to do with MyToolkit because I never saw this behavior until recently (I have been implementing MyToolkit navigation in all of my apps), although I don't really use my apps myself lol, so I can't know for sure.

This is the problem:

1 - I open my app and I let it go to the home page.
2 - I minimize my app and go away, doing other things.
3 - When I open my app again (clicking on the taskbar, I'm using Windows 8.1), the app launches all over again (splash screen, login page and then home page).

This doesn't happen every time, i.e. there are some situations where I do the same thing and the app is there, in the same page that I left it. Do you have an opinion about this?

Thank you.
Coordinator
Jan 26, 2015 at 9:53 PM
I think this is because suspend resume is not correctly implemented (eg you disabled suspensionmanager..)
Jan 26, 2015 at 10:51 PM
Good evening.

Well, to be honest with you I have commented my RestoreStateAsync override and indeed the app has been running for half an hour now and it's still kicking, so you were probably right all along...

I will immediately restore this in all of my apps, since this disadvantage is way worse than what I was trying to avoid.

Thank you very much!
Jan 29, 2015 at 10:40 PM
Good evening.

I have been following the YouTube issue here (I had that problem too).

I don't know if the latest NuGet package contains only that fix or also other stuff that you have been doing, but since updating my references my apps can NO LONGER SHOW THE FIRST PAGE after the splash screen, i.e. I only get a BLACK SCREEN. I can confirm this situation both on Windows 8.1 and in Windows Phone 8.1 too. This is very serious, so PLEASE fix this as soon as you can.

Thank you.
Coordinator
Jan 30, 2015 at 8:21 AM
Hi,
Please updated to version 2.3.26, this should fix your problem.
Rico
Jan 30, 2015 at 7:45 PM
Good evening.

I appreciate the quick fix (and the YouTube bug too).

Thank you.
Coordinator
Jan 30, 2015 at 7:49 PM
Everything working again?
If you like the libraray please review and/or follow it...
Jan 30, 2015 at 7:58 PM
Good evening.

I believe so, pages are opening correctly and transitions executed are my custom ones too, so the most basic things are okay, I haven't checked anything more yet.

I barely know CodePlex but I just clicked Follow and made a 5-star rating of this package! :)

Thank you.
Feb 3, 2015 at 1:08 AM
Good evening.

Another day, another issue. :)

Right now I'm developing for Windows Phone 8.1. Everything has been running smoothly, i.e. I have been using MyToolkit effortlessly just as it was Windows 8.1 (all my previous issues were on Windows 8.1). I was actually just finishing the development when I noticed a little bug on the navigation of MyToolkit.

Here is the scenario:

1 - I open my app.
2 - I go to the start screen (with my app still opened in background)
3 - I click a secondary tile that leads my app to another page
4 - The page opens fine
5 - If I click the back button now (the hardware one), I get the following exception and stack trace:
{System.ArgumentException: Value does not fall within the expected range.
   at System.Runtime.InteropServices.WindowsRuntime.IVector`1.InsertAt(UInt32 index, T value)
   at System.Runtime.InteropServices.WindowsRuntime.VectorToListAdapter.InsertAtHelper[T](IVector`1 _this, UInt32 index, T item)
   at System.Runtime.InteropServices.WindowsRuntime.VectorToListAdapter.Insert[T](Int32 index, T item)
   at MyToolkit.Paging.MtFrame.AddNewPageToGridIfNotSequential(PageInsertionMode insertionMode, MtPageDescription newPage)
   at MyToolkit.Paging.MtFrame.<NavigateWithAnimationsAndCallbacksAsync>d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at MyToolkit.Paging.MtFrame.<GoForwardOrBack>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state)
   at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()}
SuspensionManager is activated, as we agreed upon earlier, so it can't be that. Can you please help me on this? (this scenario is very specific and rare, so I don't think I'll be holding up my certification because of it, but still it would be nice for the issue to be resolved anyway)

Thank you.
Coordinator
Feb 3, 2015 at 1:34 PM
I could not reproduce the problem in my sample app (but I found another bug while suspending/resuming). Can you provide a sample app where this problem can be reproduced?
Feb 4, 2015 at 9:34 PM
Good evening.

I have found the source of the problem: my custom page transition. When I commented the line that sets my transition (and navigation was made using the default Windows Phone transition), the problem went away. Can you look at the code of my custom class to see if anything can be done to fix the problem while maintaining the idea behind my transition?
using System;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using MyToolkit.Paging.Animations;

namespace GooglePlus.Windows.Helpers
{
    public class PushPageAnimation : IPageAnimation
    {
        private int _lastAnimationType;

        public Task AnimateForwardNavigatingFromAsync(FrameworkElement previousPage, FrameworkElement nextPage)
        {
            var random = new Random();

            _lastAnimationType = random.Next(1, 5);

            return Push(previousPage, nextPage, _lastAnimationType);
        }

        public Task AnimateForwardNavigatedToAsync(FrameworkElement previousPage, FrameworkElement nextPage)
        {
            var completion = new TaskCompletionSource<object>();

            completion.SetResult(null);

            return completion.Task;
        }

        public Task AnimateBackwardNavigatingFromAsync(FrameworkElement previousPage, FrameworkElement nextPage)
        {
            var random = new Random();

            _lastAnimationType = random.Next(1, 5);

            return Push(previousPage, nextPage, _lastAnimationType);
        }

        public Task AnimateBackwardNavigatedToAsync(FrameworkElement previousPage, FrameworkElement nextPage)
        {
            var completion = new TaskCompletionSource<object>();

            completion.SetResult(null);

            return completion.Task;
        }

        public PageInsertionMode PageInsertionMode
        {
            get { return PageInsertionMode.ConcurrentBelow; }
        }

        /// <summary>
        /// Pushes the specified previous page.
        /// </summary>
        /// <param name="previousPage">The previous page.</param>
        /// <param name="nextPage">The next page.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        private static Task Push(UIElement previousPage, UIElement nextPage, int type)
        {
            if (nextPage == null)
            {
                return Task.FromResult<object>(null);
            }

            previousPage.RenderTransform = new CompositeTransform();
            nextPage.RenderTransform = new CompositeTransform();

            var duration = TimeSpan.FromSeconds(0.25);
            var story = new Storyboard();
            var previousAnimation = new DoubleAnimation();
            var nextAnimation = new DoubleAnimation();

            switch (type)
            {
                case 1:
                    previousAnimation = new DoubleAnimation
                    {
                        Duration = duration,
                        From = 0,
                        To = Window.Current.Bounds.Height,
                    };
                    nextAnimation = new DoubleAnimation
                    {
                        Duration = duration,
                        From = -Window.Current.Bounds.Height,
                        To = 0
                    };
                    break;
                case 2:
                    previousAnimation = new DoubleAnimation
                    {
                        Duration = duration,
                        From = 0,
                        To = -Window.Current.Bounds.Height,
                    };
                    nextAnimation = new DoubleAnimation
                    {
                        Duration = duration,
                        From = Window.Current.Bounds.Height,
                        To = 0,
                    };
                    break;
                case 3:
                    previousAnimation = new DoubleAnimation
                    {
                        Duration = duration,
                        From = 0,
                        To = Window.Current.Bounds.Width,
                    };
                    nextAnimation = new DoubleAnimation
                    {
                        Duration = duration,
                        From = -Window.Current.Bounds.Width,
                        To = 0,
                    };
                    break;
                case 4:
                    previousAnimation = new DoubleAnimation
                    {
                        Duration = duration,
                        From = 0,
                        To = -Window.Current.Bounds.Width,
                    };
                    nextAnimation = new DoubleAnimation
                    {
                        Duration = duration,
                        From = Window.Current.Bounds.Width,
                        To = 0,
                    };
                    break;
            }

            switch (type)
            {
                case 1:
                case 2:
                    Storyboard.SetTargetProperty(previousAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)");
                    Storyboard.SetTargetProperty(nextAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)");
                    break;
                case 3:
                case 4:
                    Storyboard.SetTargetProperty(previousAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
                    Storyboard.SetTargetProperty(nextAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
                    break;
            }

            Storyboard.SetTarget(previousAnimation, previousPage);
            Storyboard.SetTarget(nextAnimation, nextPage);

            story.Children.Add(previousAnimation);
            story.Children.Add(nextAnimation);

            var completion = new TaskCompletionSource<object>();

            story.Completed += delegate
            {
                completion.SetResult(null);
            };

            story.Begin();

            return completion.Task;
        }
    }
}
Or perhaps animations have to be slightly different in Windows Phone than in Windows? Because I'm using the exactly same file than the Windows version (it's a Universal App).

Thank you.
Feb 19, 2015 at 12:13 AM
Good evening.

I am still waiting for your reply on the last post.

There's something else that has been happening in my Windows Phone 8.1 app and it's much worse than the aforementioned issue. It's about memory leaks: the memory usage of my app keeps building and eventually the app crashes. Now, I know that the majority of my app's pages have ListViews that use a very complex UserControl that has numerous controls on it. I can work a little bit on that because I have seen that if I remove some of those controls (the MapControl and the MediaElement, for example), the memory crash takes much longer to happen.

However, just for the sake of speed when releasing this important bug fix for my app, I thought that I could just disable MtPage's NavigationCacheMode and thus pages would not be cached, so that only the current one would be occupying memory, no matter how much it would be. The problem is that neither by setting MtPage's NavigationCacheMode to Disabled or setting MtFrame's DisableCache to True the problem goes away. In fact, nothing seems to change: the memory just keeps increasing like before.

Is your code ignoring these changes? Can you help me out on this please?

Thank you.
Feb 19, 2015 at 12:36 AM
Good evening.

Here's two more things that I've tried that DO NOT work:

1 - Clearing pages in the Pages property of the MtFrame (it then crashes when going back of forward; probably need to do something more than that...)
2 - Setting CacheSize of 0 of the InternalFrame property of the MtFrame

Thank you.
Coordinator
Feb 23, 2015 at 8:46 AM
Can you add me in skype so that we can find a solution: rico.suter
Apr 3, 2015 at 2:46 PM
Good afternoon.

The newest release of the toolkit has broken my pages: they became all black (only popups are shown in the top-left corner); this has happened in the past already, so please fix this issue as soon as possible (I was working on a new app).

Thank you.
Coordinator
Apr 10, 2015 at 10:11 PM
Please test with v2.3.30, I think v2.3.29 is broken...
Apr 10, 2015 at 10:26 PM
Good evening.

Yes, the new version seems to be working well again.

Thank you.