ellemayo
ellemayo

Reputation: 3258

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.

Upvotes: 6

Views: 2647

Answers (7)

Tuukka
Tuukka

Reputation: 31

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.

Upvotes: 3

George M Ceaser Jr
George M Ceaser Jr

Reputation: 1781

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:

  1. In the XAML - I added an event handler for the Loaded event of the map. Example: Loaded="myMap_Loaded"
  2. 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(); }

  1. 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.

Upvotes: 0

CAMOBAP
CAMOBAP

Reputation: 5657

I had this problem for MapAnimationKind.Linear but for MapAnimationKind.None it works without any problem

map.SetView(LocationRectangle.CreateBoundingRectangle(...), MapAnimationKind.None);

Upvotes: 0

ellemayo
ellemayo

Reputation: 3258

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);

Upvotes: 4

Faturek
Faturek

Reputation: 44

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.

Upvotes: 0

alkasai
alkasai

Reputation: 4023

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.

Upvotes: 2

sadify
sadify

Reputation: 122

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.

Upvotes: 0

Related Questions