Windows Phone App Freezing while loading main page? - c#

My windows phone app is freezing while loading the main page. I have set breakpoints on the main contructor and it fires the OnNavigatedTo event but never fires the "Loaded" event. It gets through the InitializeComponent() in the contructor. It shows the splash screen and the mainpage application bar, but freezes at that point.
I have recently refactored my main namespace, which was causing the mainpage to not load. I fixed that via the Startup Object.
EVERYTHING was working before the refactoring.
What code should I include? The project is fairly large at this point, so I dont know how much you really want me posting code.
Any ideas??

Ok I found the problem. In App.Xaml.cs I made the following crucial mistake:
Here is my code:
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != null && RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
And here is what is was supposed to be:
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
Resharper thought it would be best to check if RootVisual was null first. Incredibly irritating mistake as It would just hang at the startup PNG and never load, obviously because RootVisual wasn't being set.

I've had difficulties like this before. Sounds like it's probably a problem in your XAML but without actually having your solution it's hard to tell.
Here's a couple of things you could try:
Check all your static/dynamic resources to make sure that they're all still resolving correctly.
Check that any bindings and binding converters that you're using are still resolving properly. Converters in particular, I've had issues with them in the past.
If you're getting exceptions, but not tied to a specific point in code:
Try putting breakpoints on any or all custom properties that you might be using. Properties aren't stepped into by the debugger by default. I've found this to be the cause of a number of exceptions in my own work.
Hope this helps!

Related

UI function firing before quick event finishes

I have a web browser frame docked in a Silverlight application, and sometimes full-window XAML/Silverlight UI elements can pop up over it. The old problem, which I've more-or-less fixed, is that the web frame's contents didn't seem to play nice with the Silverlight content, always wanting to be rendered on top. This isn't really an issue now since I have an event that fires whenever an application-obscuring popup appears, but now there's a new problem.
My code that launches pop-ups looks like this:
public void OnModuleShown()
{
if (ModuleShown != null)
ModuleShown(this, new ModuleShownEventArgs());
}
public void ShowModule (string uri, string headerTitle, string message, string transition = "DefaultTransition")
{
// Security and destination validation
GetInfoFromURI(uri, out contentKey, out dataKey, out securityToken);
OnModuleShown();
ShowLoadingSpinner();
_loadModule(contentKey, dataKey, securityToken, headerTitle, message, transition);
}
My code that handles the event looks like this:
private void Shell_ModuleShown(object sender, ModuleShownEventArgs e)
{
if (browserFrame.Visibility == Visibility.Visible)
{
browserFrame.Visibility = Visibility.Collapsed;
return;
}
}
The new problem is that even though I call the event before I start loading and displaying the new module, and even though all the event is doing is changing a web frame's visibility, the module tends to appear first if the loading time is short. Since the module's appearance is animated, it looks even worse since the web frame seems to be waiting for the module to finish its animation before it vanishes.
Questions
Is there some kind of threading method I can use to address this? I really don't want to use Thread.Sleep but it's the only one I know of that would fix this without large program changes I can't make. Even better would be if there was a way to get this web frame to play along with Z-indexes or something similar.
I am using Visual Studio 2013, and my project's .NET Framework version is 4.0.

Black areas on inherited ToolStrip [duplicate]

I use StatusStrip that contains ToolStripStatusLabel. OS - Windows 7, framework 2.0.
Usually all displayed normal, but sometimes ToolStripStatusLabel looks like black box:
I read that windows bug, but how I can fix it?
This is an obscure bug, triggered when you display the form with the Windows toolbar overlapping your StatusStrip. Moving the window away from the toolbar doesn't get the ToolStripItems on the status strip repainted properly. You'll find a bit of background in this forum post. There was a weak promise for a future fix for it, no idea if that ever happened. Probably not if you are running this on Win7.
You'll need to pay more attention to the position of the window, making sure that parts of it don't disappear underneath the toolbar. In general something you'd always consider, extra important as long as this bug doesn't get fixed. If you don't want to nail down the startup position (you ought to, users tend to like a window getting redisplayed where they last moved it) then simply change the form's StartPosition property to "CenterScreen".
This bug has never been fixed. It was in framework 2 and is still in framework 4.
The answer from Hans is a copy of the answer in social.msdn.microsoft.com.
But it is not helpful for me because "CenterScreen" does not solve the problem.
The cause of the problem is not the Windows Taskbar. The cause is a bug that does not draw the StatusStrip when the main Form is behind ANY other window at the first moment of drawing the StatusStrip. But this will also happen when you start the new process with Process.Start() from another process and the new process opens behind the window of another process.
I found a much better solution than the one proposed by Microsoft.
First I tried with
statusStrip.Invalidate();
but it does not work. So we need a stronger way to force Windows to redraw the StatusStrip. Important: The redrawing must happen when the Form with the StatusStrip is ALREADY in foreground! This is so easy that I don't understand why Microsoft does not suggest this method.
Timer mi_StatusTimer = new Timer();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
mi_StatusTimer.Interval = 500;
mi_StatusTimer.Tick += new EventHandler(OnTimerBugFix);
}
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
mi_StatusTimer.Start();
}
void OnTimerBugFix(object sender, EventArgs e)
{
mi_StatusTimer.Stop();
statusStrip.Hide();
Application.DoEvents();
statusStrip.Show();
}

Slow navigation between pages

I am developing an app for Windows Phone 8 in VS2012 and My StartUp Project page is SetProfile.XAML which creates the profile for the first time, but if the user is entering the app second time, the page must not appear because there is already an existing profile.
So I have this code for the "Loaded" event handler, which checks if there is a created profile and if there is, navigates to MainPage page.
private void PhoneApplicationPage_Loaded_1(object sender, RoutedEventArgs e)
{
if (Flag.Contains("true"))
{
if (IsolatedStorageSettings.ApplicationSettings.Contains("player1"))
if (!(Flag.Contains("false")))
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
}
The problem is when I enter a second time, I see a blink of the SetProfile.XAML page then it navigates (it's like milliseconds), but I still can see it.
Is there any way I can make it faster so the user won't see it?
There is a very good blogpost about how to 'navigate' to a screen that is not always needed up on Shawn's blog here http://www.visuallylocated.com/post/2012/06/18/Using-a-custom-UriMapper-to-navigate-to-a-login-screen.aspx
The trick is to use a custom UriMapper class that checks all the info and determines the correct navigation uri.
You use this class in your app.xaml.cs - Application_Launching and Application_Activated
you see blink as you have used "Loaded" event,it loads page in run time and must not used unnecessary.
You must use "OnNavigatedTo" event for these normal scenarios.

Map.SetView() on Windows Phone 8

Is there a specific time in the page's lifecycle that the Map.SetView() function should be called? In our app we use this on various map objects and it seems to work randomly, sometimes perfectly and sometimes with no effect but also no exception.
example code:
RouteMap.SetView(LocationRectangle.CreateBoundingRectangle(DirectionCoordinates));
Where RouteMap is the mapping component and DirectionCoordinates contains the start/end coordinates for the map.
I can see that the bounding box is being created properly, but the map's positioning is not always being affected even loading the same data. If I add a break point it does seem to work, so I was assuming it had something to do with the map loading, but adding the SetView() functionality to the Loaded event has the same issue. We currently process the map information in the page Loaded event.
Update
I've been testing more and added events to what I could, I know for a fact that the MapLoaded event is being called before SetView. After SetView is called, it is working sometimes and not others. Neither ViewChanging or ViewChanged events are called.
This is obviously not the best solution, but there must be something that is not quite finished loading when the Loaded event is called that is preventing this from finishing.
I added a 100ms sleep to the Map_Loaded event and it has solved the problem I was having.
System.Threading.Thread.Sleep(500);
update
100ms isn't working for some people, you may want to play around with the numbers, 200, 500 etc. It's still a very short delay on the map's load time. I have contacted Microsoft about this and they have told me that they are looking into the issue and we will hopefully have some sort of response from them shortly.
update and edit
Use the following code instead to prevent UI hanging:
await Task.Delay(250);
I tackled this issue using ResolveCompleted event and boolean flag.
private void Map_ResolveCompleted(object sender, MapResolveCompletedEventArgs e)
{
if (this.zoomReq)
{
this.zoomReq = false;
if (this.locationList != null && this.locationList.Count > 0)
{
var viewRect = LocationRectangle.CreateBoundingRectangle(this.locationList);
this.Map.SetView(viewRect);
}
}
}
There is noticeable pause before map zooms but at least this seems to work all the time. The flag is needed because ResolveCompleted is fired every time the map moves.
I was both constructing a map layer (Microsoft.Phone.Maps.Controls.MapLayer) and setting the view (public void SetView(LocationRectangle boundingRectangle);) in an async method:
public async Task CreateMap()
{
map.Add(mapLayer);
map.SetView(locationRectangle);
}
I was doing some loading, that's why I used async.
This would only set the view once, the first time I navigated to the page.
The solution was to dispatch the set view call:
public async Task CreateMap()
{
map.Add(mapLayer);
Dispatcher.BeginInvoke(() =>
{
map.SetView(locationRectangle);
});
}
Hope that helps.
The Loaded event is the proper place for SetView(). You could try creating your rectangle in you OnNavigatedTo method. When I'm working with locations I always start my watcher in OnNavigatedTo and work with any map layers in _Loaded.
I worked myself some time at this problem. It didn't help to put most of the stuff to load into the constructor of the page. I tried to the trick with System.Threading.Thread.Sleep(500) but it took far beyond 500ms to take effect and this wasn't acceptable for me. For some people it helped to trigger an ZoomLevelChanged event and set the view in it. For myself I used a DispatcherTimer in which I used SetView() and fired an `ViewChanging´ event to stop the timer. If you use an animation the difference is pretty small.
I had this problem for MapAnimationKind.Linear but for MapAnimationKind.None it works without any problem
map.SetView(LocationRectangle.CreateBoundingRectangle(...), MapAnimationKind.None);
I had a very similar problem. Basically the setview of map would work the first time a page loaded (i.e. after all the data had finished loading) but if I left the page and came back and did not need to reload all the data, it did not work. While debugging, it seemed like I was setting the information for the map before it was finished loading.
So what I did to resolve the challenge was:
In the XAML - I added an event handler for the Loaded event of the map.
Example: Loaded="myMap_Loaded"
In the myMap_Loaded event, I simply called an async method to wait for the data to load then map
it.
Example:
private void myMap_Loaded(object sender, RoutedEventArgs e)
{
WaitAndLoadMap();
}
Coded the WaitAndLoadMap method to wait for the data to finish loading before loading the
map.
private async void WaitAndLoadMap()
{
//Check if the data is loaded and if it is not - loop.
while (!App.NearbyLocationsViewModel.IsLocationDataLoaded)
await Task.Delay(250);
//Load the map content and set the mapview.
}
It seems to be working. Hope this helps others.

Skip a page when the back button is pressed, WP7

In the current released version of WP7 you have no programmatic control over the page stack.
I start at A, go to B, and then C. B is the data entry page for new items, so coming back from C I want to logically land at A. Currently I listen for navigation on B that comes from C and force another back onto A. However, the event doesn't happen soon enough to stop the page from displaying on-screen.
A -> B -> C
C -> A
A is the top level list page. B is the new item page. C is the item detail page.
This only occurs on one form so far so my workaround is to override OnNavigatedTo in the page I want to skip, and call "go back" programmatically. However, this has the undesired effect of briefly showing the page and then immediately navigating off of it.
Is there a workable way to stop the flicker?
Should my workaround instead be to take full control of page navigation, including go backs? This will leave the page stack is a strange state, but that would be hidden from the user if I control all navigation.
I know there is a new feature in Mango to pop a page from the page stack programmatically, but I'm curious to know if there is a solution to the problem in the released version.
Another motivation for this is I don't know what version will be best to target, the latest, or the one that is just enough for the app. For the time being I'm sticking with the live version.
You should read this blog post on solving circular navigation issues and you can download this recipe code which demonstrates non-linear navigation.
I have stopped the flickering by making the root frame transparent for the duration of the skip. This example isn't straight from my code.
Firstly on the page you wish to skip, override OnNavigatedTo and test to see where you have come from (this is where my code gets specific, I keep track of where I am):
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// If I've come from page C, go back again.
NavigationService.GoBack();
}
Secondly, in the main App.xaml.cs register an event handler for Navigating (I put it in public App() constructor):
RootFrame.Navigating += RootFrame_Navigating;
Finally, flesh them out to hide the frame and show it again for the duration of the skip:
private bool _skipped;
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
{
RootFrame.Opacity = 100;
RootFrame.Navigated -= RootFrame_Navigated;
}
private void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (_skipped)
{
_skipped = false;
RootFrame.Navigated += RootFrame_Navigated;
}
if (e.NavigationMode == NavigationMode.Back &&
e.Uri.OriginalString.Contains("ThePage.xaml"))
{
RootFrame.Opacity = 0;
_skipped = true;
}
}
The code to determine when to make the page transparent is also different in my actual code, but I've added an implementation to the answer for illustration. This is almost identical to the code in the recipe linked in another answer, but doesn't involve needing to use a third party DLL.
I provided my own answer because I've seen the sources provided in the other answers before, but never paid attention to the code for hiding the root frame. I am not using the Non-Linear Navigation Service, just the code fragment for frame transparency (I don't need it to detect circular navigation as I'm well aware of the design choices I make in the app and can spot them myself :-)
This suffices as a workaround in the (currently) one case I have where I need to skip a page that doesn't make sense when going back. I'd like to think when Mango comes out I will be best placed targeting the latest version, so this code will soon be defunct.
Sources:
App Hub code recipe for Non-Linear Navigation
Non-Linear Navigation Service Blog Post
There is no way to do it before Mango, except with the flickering way you already know.
In Mango, you can use NavigationService.RemoveBackEntry.
And it's more a question of a bad application design, than anything else. You shouldn't require a immediate page for anything.
Your workaround should be to design a application structure that doesn't require any immediate pages.

Categories