Category Archives: Mobile Development

Windows Phone Listbox: ensure ItemSource is bound before SelectedItem

Just spent a couple of hours trying to figure out why setting the SelectedItem of a ListBox kept crashing the application. It turns out that setting the ItemSource binding before the SelectedItem is a no go as per this StackOverflow posting.

So beware when designing your Windows Phone pages. For example, look at the snippet below.

 <toolkit:ListPicker            
            Header="Select a stop"
            Margin="{StaticResource PhoneMargin}"
            Grid.Row="2" 
            Grid.Column="0"
            SelectionMode="Single"
             ItemsSource="{Binding Stops}"
            SelectedItem="{Binding SelectedStop, Mode=TwoWay}">

If you place SelectedItem before ItemSource application will crash when you attempt to programmatically set the SelectedItem.

Simple C# Interlocked use case

Original code in a ViewModel for a Windows Phone application looked like this:

 private readonly object _lock = new object();
 private int _secondsToNextRefresh;
 public int SecondsToNextRefresh
 {
 get { return _secondsToNextRefresh; }
 set { _secondsToNextRefresh = value; RaisePropertyChanged(() => SecondsToNextRefresh); }
 }

 protected void ResetRefreshTimer()
 {
 if (_refreshTimer == null)
 {
  _refreshTimer = new Timer(arg =>
  {
    if (SecondsToNextRefresh == 0)
    {     
     GetData();
     SecondsToNextRefresh = GetSecondsToNextRefresh();
    }
    else
    { 
     ModifySecondsToNextRefresh(SecondsToNextRefresh - RefreshPeriodInSec);
    }
    },null, 0, RefreshPeriodInSec * Constants.MilliSecsPerSec);
  } 
 }

protected int ModifySecondsToNextRefresh(int value)
 { 
   lock (_lock)
  {
   SecondsToNextRefresh = value; 
  }
  return SecondsToNextRefresh;
}

Upon further inspection of the code, it appeared to me that I can take advantage of the higher performance C# Interlocked methods.

Changing the above code to:


_refreshTimer = new Timer(arg =>
{
 if (_secondsToNextRefresh == 0)
 {   
   secsToNextRefresh = GetSecondsToNextRefresh();
   GetData(); 
  }
  ModifySecondsToNextRefresh(secsToNextRefresh) 

},null, 0, RefreshPeriodInSec * Constants.MilliSecsPerSec);

protected int ModifySecondsToNextRefresh(int value)
{ 
  var valueToReturn = Interlocked.Exchange(ref _secondsToNextRefresh, value);
  RaisePropertyChanged(() => SecondsToNextRefresh);
  return valueToReturn;
}

Based on advise from Writing High Performance .NET Code, surely is the preferred locking mechanism in this scenario.

Windows phone map control doesn’t render in ContentControl

While working on a mapping framework agnostic of GIS implementation, I attempted creating a MapView that will host a vendor specific map object as follows:


<!--LayoutRoot is the root grid where all page content is placed-->
 <Grid x:Name="LayoutRoot" Background="Transparent">
 <Grid.RowDefinitions>
 <RowDefinition Height="Auto"/>
 <RowDefinition Height="*"/>
 </Grid.RowDefinitions>

<!--TitlePanel contains the name of the application and page title-->
 <StackPanel Grid.Row="0" Margin="12,17,0,28">
 <TextBlock Text="agnostic mapper" Style="{StaticResource PhoneTextNormalStyle}"/>
 <TextBlock Text="map" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
 </StackPanel>

<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

<Grid.RowDefinitions>
 <RowDefinition Height="*"/>
 <RowDefinition Height="Auto"/>
 </Grid.RowDefinitions>

<ContentControl Name="MapContentControl" Content="{Binding MainMapView, Mode=OneTime}"/>

 </Grid>
 </Grid>

The view will be bound to an instance of MapViewModel implemented as follows:


 public class MapMainViewModel : ViewModelBase, IMapViewModel
 {
  public IMapViewController MapViewController { get; protected set; }

 public MapMainViewModel(IMapViewController mapViewController)
 {
 MapViewController = mapViewController;
 }

 public object MainMapView
 {
   get
   {
    return MapViewController.GetMapObject();
   }
 }

 public IMvxCommand ShowLegendCommand
 {
  get { return new MvxCommand(() => ShowViewModel<LegendViewModel>()); }
 }

 public void DrawPendingLayers()
 {
   MapViewController.DrawPendngLayers();
 }

 protected override void Dispose(bool disposing)
 {
   if (disposing)
   {
     MapViewController.DisposeActiveMapContext();
   }
  }
 }

For some reason, yet to be determined, if the the ViewModel returns an instance of Microsoft Windows Phone Map control, we do not see anything.  We expect to see a base map of the world, like so:

windows-phone-map-does-not-display-in-contentcontrol

However, if we return an instance of ThinkGeo MapSuite Map or even ESRI ArcGIS Map controls for Windows Phone, we do see a map.

If you run into this, change the hosting container from a ContentControl to a Border control as follows:

<Border Name="MapContentControl" Child="{Binding MainMapView, Mode=OneTime}"></Border>

With this minor change, any of the three maps should be rendered correctly.