Map never renders - WebApp is set to startup

3 posts, 0 answers
  1. Derek Strickland
    Derek Strickland avatar
    5 posts
    Member since:
    May 2010

    Posted 31 Jan 2011 Link to this post

    Hi,

    I am getting nothing but a blank grey box when my map screen loads and my ItemsRequest event never fires.  I do NOT have my SL set as the startup project.  My webApp host is the startup project..  Here is my xaml, codebhind, viewmodel and dynamic source.  Any ideas what I am doing wrong?  

    XAML

    <UserControl.Resources>
            <ResourceDictionary>
                <model:MapViewModel x:Key="ViewModel" />
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="MapDictionary.xaml"></ResourceDictionary>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </UserControl.Resources>
     
        <Grid x:Name="LayoutRoot" DataContext="{StaticResource ViewModel}">
            <telerik:RadMap x:Name="Map" Provider="{Binding Provider}" Center="{Binding Center, Mode=TwoWay}" ZoomLevel="{Binding ZoomLevel, Mode=TwoWay}">
                <telerik:DynamicLayer x:Name="dynamicLayer">
                    <telerik:DynamicLayer.ZoomGridList>
                        <telerik:ZoomGrid LatitudesCount="2" LongitudesCount="2" MinZoom="3" />
                        <telerik:ZoomGrid LatitudesCount="4" LongitudesCount="4" MinZoom="9" />
                    </telerik:DynamicLayer.ZoomGridList>
                </telerik:DynamicLayer>
     
            </telerik:RadMap>
     
        </Grid>


    DynamicLayer 

    internal class MapDynamicSource : IMapDynamicSource {
         
        public MapDynamicSource(MyMapControl mapControl) {
            _model = mapControl.LayoutRoot.DataContext as MapViewModel;
     
            if (_model == null)
                MessageBox.Show("MapDynamicSource:  Model must be set on view.");
        }
     
        public void ItemsRequest(object sender, ItemsRequestEventArgs e) {
            double minZoom = e.MinZoom;
            Location upperLeft = e.UpperLeft;
            Location lowerRight = e.LowerRight;
     
            const string exceptionFormat = "Map Service Exception: {0}";
     
            if (minZoom == 3) {
                // request areas
                try {
                    ContentControl marketControl = sender as ContentControl;
     
                    int marketId = (int)marketControl.Tag;
     
                    var getMarketAreasCompletedEventArgs = new AsyncCallStatus<GetMarketAreasCompletedEventArgs>();
                    Model.MapClient.GetMarketAreasAsync(marketId, getMarketAreasCompletedEventArgs);
     
                }
                catch (Exception ex) {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                    throw new Exception(string.Format(exceptionFormat, ex.Message));
                }
            }
     
            if (minZoom == 9) {
                // request wells
                try {
                    var getDetailsCompletedEventArgs = new AsyncCallStatus<GetDetailsCompletedEventArgs>();
                    Model.MapClient.GetDetailsAsync(Convert.ToDecimal(lowerRight.Longitude),
                                                Convert.ToDecimal(upperLeft.Longitude),
                                                Convert.ToDecimal(lowerRight.Latitude),
                                                Convert.ToDecimal(upperLeft.Latitude),
                                                getDetailsCompletedEventArgs);
     
                }
                catch (Exception ex) {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                    throw new Exception(string.Format(exceptionFormat, ex.Message));
                }
            }
        }
     
        private MapViewModel _model = null;
        public MapViewModel Model {
            get { return _model; }
        }


     codebehind costructor.

    public MyMapControl() {
        InitializeComponent();
        this.dynamicLayer.DynamicSource = new MapDynamicSource(this);
    }

    And finally the ViewModel

    public class MapViewModel : ViewModelBase, INotifyPropertyChanged, IDisposable {
           public MapViewModel() {
               InitializeComponent();
           }
     
           public void SetView(MyMapControl view) {
               this.View = view;
           }
     
           #region Initialization and data access
           private void InitializeComponent() {
               ConfigureClients();
               GetBingKey();
               this.ZoomLevel = 4;
               this.Center = new Location(37.684297, -99.06924);
           }
     
           private void ConfigureClients() {
               //Omitted:  Sets up Service Client and registers callbacks 
           }
     
           public virtual void SetProvider() {
               BingMapProvider provider = new BingMapProvider(MapMode.Aerial, true, this.BingKey);
               this.Provider = provider;
           }
     
           internal void GetBingKey() {
               var getBingKeyCompletetedEventArgs = new AsyncCallStatus<GetBingKeyCompletedEventArgs>();
               MapClient.GetBingKeyAsync(getBingKeyCompletetedEventArgs);
           }
     
           private void OnGetBingKeyCompleted(object sender, GetBingKeyCompletedEventArgs e) {
               if (e.Error != null)
                   throw e.Error;
     
               this.BingKey = e.Result;
               this.SetProvider();
           }
     
           #endregion
     
           #region properties
           public string BingKey { get; set; }
     
           protected BingMapProvider Provider { get; set; }
     
           public MapServiceClient MapClient { get; set; }
     
           public MyMapControl View { get; private set; }
     
           private int _zoomLevel;
           public int ZoomLevel {
               get {
                   return this._zoomLevel;
               }
               set {
                   if (this._zoomLevel != value) {
                       this._zoomLevel = value;
                       this.OnPropertyChanged(() => this.ZoomLevel);
                   }
               }
           }
     
           private Location _center;
           public Location Center {
               get {
                   return this._center;
               }
               set {
                   if (this._center != value) {
                       this._center = value;
                       this.OnPropertyChanged(() => this.Center);
                   }
               }
           }
     
           private ObservableCollection<MarketMapAdapter> _markets = null;
           public ObservableCollection<MarketMapAdapter> Markets {
               get { return _markets; }
               set {
                   _markets = value;
                   this.OnPropertyChanged(() => this.Markets);
               }
           }
     
           private ObservableCollection<AreaMapAdapter> _areas = null;
           public ObservableCollection<AreaMapAdapter> MarketAreas {
               get { return _areas; }
               set {
                   _areas = value;
                   this.OnPropertyChanged(() => this.MarketAreas);
               }
           }
     
           private ObservableCollection<DetailMapAdapter> _details = null;
           public ObservableCollection<DetailMapAdapter> Details {
               get { return _details; }
               set {
                   _details = value;
                   this.OnPropertyChanged(() => this.Details);
               }
           }
     
           public Action<ObservableCollection<MarketMapAdapter>> MarketsCompletedCallback { get; set; }
     
           #endregion
     
           #region Map Callbacks
     
           private void OnGetDetailsCompleted(object sender, GetWellDetailsCompletedEventArgs e) {
                //Ommitted: Not relevant yet since items request never fires
           }
     
           private void OnGetMarketAreasCompleted(object sender, GetWellMarketAreasCompletedEventArgs e) {
                //Ommitted: Not relevant yet since items request never fires
           }
     
           private void OnItemsRequestCompleted(object sender, ItemsRequestEventArgs e) {
      //Ommitted: Not relevant yet since items request never fires
           }
     
           private void BindDetails(ItemsRequestEventArgs e) {
               //Ommitted: Not relevant yet since items request never fires
           }
     
           private void OnDetailMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
    //Omitted:  Same as example code
           }
     
           private void OnAreaMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
                //Omitted:  Same as example code 
           }
           #endregion
     
           protected override void Dispose(bool disposing) {
               //Ommitted
           }


    It seems to me that this matches the example, but as I stated the ItemsRequest event never fires so clearly I am doing something wrong.  
  2. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 03 Feb 2011 Link to this post

    Hello Derek Strickland,

    In your case it looks like the map provider is never set to RadMap control. In your XAML RadMap control bind RadMap.Provider to the Provider property of the view model. I've inspected your code and found that Provider property in your map view model is defined as following:

    protected BingMapProvider Provider { get; set; }

    There are 2 major problems here:

    1. According to the bindings rules in the Silverlight you can't bind to the protected properties. Provider property in your view model must be public.

    2. The setter of the Provider property do not call any kind of the OnPropertyChanged method. So Silverlight binding engine will never be informed about value change for this property. So new value of the provider never will be passed to the RadMap control through the binding. The Provider property in your view model should looks similar to the following:

    private MapProviderBase mapProvider;
    public MapProviderBase Provider 
    {
        get
        {
            return this.mapProvider;
        }
      
        set
        {
            this.mapProvider = value;
            this.OnPropertyChanged("Provider");
        }
    }


    Regards,
    Andrey Murzov
    the Telerik team
    Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
  3. DevCraft banner
  4. Derek Strickland
    Derek Strickland avatar
    5 posts
    Member since:
    May 2010

    Posted 03 Feb 2011 Link to this post

    Ever stare at something so long it ceases to have meaning?  Wow, sorry man.  Of course I have to support INotifyPropertyChanged.  How silly of me.  Sorry and thanks for the code review.  
Back to Top