Creating a Numbers only TextBox

So this isn’t a major problem, but in an app like Shoppers Calculator, there are various places where numbers get entered, and a lot of repeat code to validate entry, or limit the user to a certain number of decimal places, or even just to stop them pressing the decimal key twice.  It makes sense, therefore, to wrap all that up into a re-usable control. So here’s what it ought to do:

  • Force the number keypad
  • Ensure that only one decimal place can be entered
  • Allow the developer to restrict the length or the number,
  • Check that if you try to paste text in that’s not a number, it doesn’t allow it.

You can get the source code and a dll containing the control from here.  Compatibility is with both Windows Phone 7 and Windows Phone 8.

So getting started then, we don’t want to create this from scratch so add a new class, name it and have it inherit from System.Windows.Controls.TextBox. In the constructor, we will set the InputScope to satisfy the first requirement.

public class NumberTextBox: TextBox
{
public NumberTextBox()
: base()
{
  //Set the input scope - this forces the Numberic Keypad. You can override it by setting the property in XAML, but shouldn't.
  this.InputScope = new InputScope { Names = { new InputScopeName() { NameValue = InputScopeNameValue.Number } } };
}

Next, create dependency properties for any extra’s you want the developer to control through XAML. In my case, that’s properties for the max number of whole digits, and the max number of decimal places.  If you don’t know much about dependency properties, take a read through the WPFTutorial.net article on Dependency Properties before continuing.

///
/// The number of digits allowed before any decimal place. -1 = infinate. 0 or greater limits it. Default: -1;
///
public static readonly DependencyProperty WholeNumbersProperty = DependencyProperty.Register("WholeNumbers", typeof(int), typeof(NumberTextBox), null); 
public int WholeNumbers 
{ 
   get { return (int)GetValue(WholeNumbersProperty); } 
   set { SetValue(WholeNumbersProperty, value); } 
}
 ///
/// The number of digits allowed after any decimal place. -1 = infinite, 0 blocks decimal point and numbers after that. 
/// Greater than 0 caps decimals to the given max. Default: -1 
///
public static readonly DependencyProperty DecimalPlacesProperty = DependencyProperty.Register("DecimalPlaces", typeof(int), typeof(NumberTextBox), null); 
public int DecimalPlaces 
{ 
  get { return (int)GetValue(DecimalPlacesProperty); } 
  set { SetValue(DecimalPlacesProperty, value); } 
}

///
/// Should a message be displayed when pasting invalid text? Default: true 
///
public static readonly DependencyProperty ShowMessageProperty = DependencyProperty.Register("ShowMessage", typeof(bool), typeof(NumberTextBox), null); 
public bool ShowMessage 
{
  get { return (bool)GetValue(ShowMessageProperty); } 
  set { SetValue(ShowMessageProperty, value); } 
} 

///
/// Allow number rules for WHole NUmber and Decimal Places to be broken. 
/// Useful if you want to show validation error rather than just not allowing the number entry at all. If you use this, remember to bind to the TextValidationFailed event. 
/// Default: false 
///
public static readonly DependencyProperty BreakingNumberRulesIsAllowedProperty = DependencyProperty.Register("BreakingNumberRulesIsAllowed", typeof(bool), typeof(NumberTextBox), null); 
public bool BreakingNumberRulesIsAllowed 
{ 
  get { return (bool)GetValue(BreakingNumberRulesIsAllowedProperty); } 
  set { SetValue(BreakingNumberRulesIsAllowedProperty, value); } 
}

To check for valid text entry, we need to override the OnKeyDown event. Here we check for adding multiple decimal points, the maximum number of decimals being reached (“Separator” in the snippet below hold a string representing the localized decimal point e.g in France it would be “,”). To check for maximum number of whole digits being exceeded, we need a check in OnKeyDown and in the TextChanged even handler (this is not an override, we bind to the even in our constructor. This is because the digit being added could be added in the middle of the text.

 //Check for various error conditions on text entry - these tests block the character pressed from being included in the text.
protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
{
    IsPasted = false; //This is used in the TextChanged handler
    //Check for multiple decimal points
    if (e.Key == System.Windows.Input.Key.Unknown)
    {
       if (Text.Contains(Separator))
       {                    
           e.Handled = true;
       }
       return;
    }
    //Check for max decimal places reached
    if (!e.Handled)
    {
       if (Text.Contains(Separator) && DecimalPlaces > 0)
       {
           string check = Text.Substring(Text.IndexOf(Separator));
           if (check.Length > DecimalPlaces)
           {
               e.Handled = true;                        
           }
        }
   }
   //Check for max whole numbers reached if decimals are blocked
   if (WholeNumbers > 0 && !Text.Contains(Separator))
   {
       if (Text.Length >= WholeNumbers)
       {                    
          e.Handled = true;
          return;                    
       }
   }
   base.OnKeyDown(e);
}

Lastly, we need to handle copy/past and make sure text being pasted into the box is a number. To do this, we put a flag in the OnKeyDown event handler which is checked in the TextChanged event – this tells us if a key was pressed on the keyboard or not to get the number in there – or, if it was copied (i.e no key was pressed.  In TextChanged, if this flag has not been changed, we have the same checks there that would be done in the OnKeyDown method.

//Check for more errors on text entry that can't be immdiatley covered by OnKeyDown
//these tests revert the text back to how it was before OnKeyDown
void NumberTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
   //IsPasted defaults true, and is set false by OnKeyDown
   if (IsPasted)
   {
      //check pasted text represents a number (as long as the inputscope is number, this should only occur for pasted text)
      decimal d = 0;
      if (this.Text.Length > 0 && (Text != Separator || (Text == Separator && DecimalPlaces == 0)))
      {
         //Check for multiple decimal points
         if (Text.Count(x => x == Separator.First()) > 1)
         {
             this.Text = _text; 
             return;
         }

         //Check it's a number
         if (!decimal.TryParse(this.Text, out d))
         {
             this.Text = _text; 
             return;
         }

         //Check for max decimal places reached                    
         if (Text.Contains(Separator) && DecimalPlaces > 0)
         {
             string check = Text.Substring(Text.IndexOf(Separator));
             if (check.Length > DecimalPlaces)
             {
                this.Text = _text; 
                return;
             }
        }
        //Check for max whole numbers reached if decimals are blocked
        if (WholeNumbers > 0 && !Text.Contains(Separator))
        {
           if (Text.Length >= WholeNumbers)
           {
              this.Text = _text; 
              return;
           }
        }

        //check that text fits for whole numbers with decimals
        if (WholeNumbers > 0 && !(Text.Length > 0 && Text.Last() == Separator.First()))
        {
            string wholeCheck = Text.Substring(0, Text.Contains(Separator) ? Text.IndexOf(Separator) : Text.Length);
            if (wholeCheck.Length > WholeNumbers)
            {
                this.Text = _text; 
                return;
            }
        }                    
     }
  }
  else
  {
     //check that text fits for whole numbers with decimals
     if (WholeNumbers > 0 && !(Text.Length > 0 && Text.Last() == Separator.First()))
     {
         string wholeCheck = Text.Substring(0, Text.Contains(Separator) ? Text.IndexOf(Separator) : Text.Length);
         if (wholeCheck.Length > WholeNumbers)
         {
             this.Text = _text; 
             return;
         }
     }  

     //Reset IsPasted for next input
     IsPasted = true;
  }
  _text = this.Text;
}

Usage

To use it, add a reference at the top of the XAML page, to the library /namespace the control is in. Then, when you want to create one, use the following tag (or drag one on screen.

<UserControl x:Class="ExampleProject.ExampleUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ...
    xmlns:mnd="clr-namespace:Bluechris.Controls.Phone;assembly=Bluechris.Controls.Phone"             
    ...
    d:DesignHeight="450" d:DesignWidth="480">

    <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" TextWrapping="Wrap" x:Name="Instructions" Text="Enter a number here:"/>
        <mnd:NumberTextBox x:Name="Value" Grid.Row="1" Width="150"
                 DecimalPlaces="2" 
                 WholeNumbers="6" />          
    </Grid>
</UserControl>

So in this one, I’ve added a max on the number of digits, and the decimal places.  If I try to type more than that, it just doesn’t let me.  If I copy/paste in some text that isn’t valid, it does nothing. This is great, but may not be that helpful to the user.  In NumberTextBox, I have added a message option, and an event option that can fire when validation fails.  The validation failed event has a custom EventArgs which tells us why it failed, so a message can be displayed to the user e.g “Sorry, you can’t paste that here – you need a number with only 2 decimal places, and the number you pasted had 6″.

Option 1:

<mnd:NumberTextBox x:Name="Value" Grid.Row="1" Width="150"
                 DecimalPlaces="2" 
                 WholeNumbers="6"
                 ShowMessage="true"/>

Option 2 – XAML:

<mnd:NumberTextBox x:Name="Value" Grid.Row="1" Width="150"
                 DecimalPlaces="2" 
                 WholeNumbers="6"
                 ShowMessage="false"
                 TextValidationFailed="Value_ValidationFailed"/>

Option 2 – Code Behind:

private void Value_ValidationFailed(object sender, NumberTextBoxMessageEventArgs e)
{
    switch (e.ErrorType)
    {
        case NumberTextBoxError.DoubleDecimal:
	   MessageBox.Show("Only 1 decimal place is allowed");
	   break;
	case NumberTextBoxError.TooManyDecimalPlaces:
	   MessageBox.Show("The maximum number of decimal places is" + (sender as NumberTextBox).DecimalPlaces);
	   break;
       ....
    }
}

So there you go, a reusable number text box. Hope this has been helpful.

Posted in Development, How To, Windows Phone | Tagged , , , , , , | Leave a comment

Custom Message Box

So just a quickie but for an improvement I’m making to Shoppers Calculator I decided one way to get past a hurdle I was up against was to use a MessageBox or similar to ask the user to enter some text, without taking them away from the current screen. Ah, but Messagebox just takes a caption, a message and allows OK and Cancel buttons – isn’t there a way to do a custom message box? Yes there is.

I came across this great article by Shawn Oster that described how to use CustomMessageBox via code or XAML and so I’m going to suggest you go there to take a look at it rather than me repro all the same information here.

One thing I will do though is mention something to consider if you are creating a message box in which the user will be be asked to enter text, you can save them a tap and make what is needed even more obvious by setting the focus to the text box you want them to edit.

However, the timing is crucial here – it doesn’t work to call it either before or after calling Show(), instead, bind to the Loaded event and add it there. It works beautifully:

TextBox myTextBox = new TextBox();
CustomMessageBox messageBox = new CustomMessageBox()
 {
    //Setup
    Content=myTextBox;
 };
messageBox.Dismissed += (s1, e1) =>
 {
   //handle result}
 };
messageBox.Loaded+=(s1,e1)=>
{
   myTextBox.Focus();
}
messageBox.Show();

Having done this, you will find that the moment the message box opens, so does the keypad – no big deal, but you have just saved the user the faff of tapping in the textbox which they had to do anyway, and helping the user helps the user think your app is great.

Anyway, enough for now, go and read Shawn’s post for a more detailed look at CustomMessageBox.

Posted in Development, Windows Phone | Tagged , , , | Leave a comment

Theming images – why Expression Design is great

Microsoft Expression design is a really useful tool, and it’s now free – you can download Expression Design from Microsoft right here.

“But why should I?” you may ask. I know people have their tool of choice from Photoshop, to Paint.Net, to just plain old paint for creating an icon or graphic to use in your app. And, as I discussed here, some effects can be achieved using Opacity Masks.

Expression Design can take this one step further and spit out the XAML for your image.  You can then customize the image at run time by binding the colors, or fonts, or line styles to other resources. You can even show or hide different parts of the image, just the same as you would for a Button, Textblock or other control. One use for this is avoiding light/dark theme issues, but it also gives good flexibility.

So how’s it done?

First, create an image, shape, logo or whatever in expression design.designNext, choose File, Export and select XAML Silverlight 4 / WPF Canvas

design-export

Open the XAML file in visual studio or any text editor.  In my case it looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Untitled1" Width="100" Height="100" Clip="F1 M 0,0L 100,0L 100,100L 0,100L 0,0">
 <Canvas x:Name="Layer_1" Width="100" Height="100" Canvas.Left="0" Canvas.Top="0">
  <Rectangle x:Name="Rectangle" Width="46.75" Height="44.5" Canvas.Left="5" Canvas.Top="6.6875" Stretch="Fill" Fill="#FF000000"/>
  <Rectangle x:Name="Rectangle_0" Width="46.75" Height="44.5" Canvas.Left="26.625" Canvas.Top="27.75" Stretch="Fill" Fill="#FFFF0000"/>
  <Rectangle x:Name="Rectangle_1" Width="46.75" Height="44.5" Canvas.Left="48.625" Canvas.Top="52.875" Stretch="Fill" Fill="#FF230FD2"/>
 </Canvas>
</Canvas>

The last thing is to decide how to use it.  Silverlight has to use this as a Canvas which has some limitations.  You will run into them quickly if you just add the Canvas as-is to your resource dictionary  and try and use it.  However, I can be used both in the page content, or in a resource.

The easiest way to add it is in page content, like this:

<ContentControl Grid.Row="0" >
 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Untitled1" Width="100" Height="100" Clip="F1 M 0,0L 100,0L 100,100L 0,100L 0,0">
  <Canvas x:Name="Layer_1" Width="100" Height="100" Canvas.Left="0" Canvas.Top="0">
   <Rectangle x:Name="Rectangle" Width="46.75" Height="44.5" Canvas.Left="5" Canvas.Top="6.6875" Stretch="Fill" Fill="#FF000000"/>
   <Rectangle x:Name="Rectangle_0" Width="46.75" Height="44.5" Canvas.Left="26.625" Canvas.Top="27.75" Stretch="Fill" Fill="#FFFF0000"/>
   <Rectangle x:Name="Rectangle_1" Width="46.75" Height="44.5" Canvas.Left="48.625" Canvas.Top="52.875" Stretch="Fill" Fill="#FF230FD2"/>
  </Canvas
 </Canvas>
</ContentControl>

However, this is only half of it, as you see – the top left square of my design is missing.

badimage

Next, I change the color for the first rectangle:

<Rectangle x:Name="Rectangle" Width="46.75" Height="44.5" Canvas.Left="5" Canvas.Top="6.6875" Stretch="Fill" Fill="{StaticResource PhoneForegroundBrush}"/>

That PhoneForgroundPrush will change depending on the light or dark theme, but I could use custom colors here, if I’d decided to offer a choice of my own themes to users. In this case, it now looks like:

goodimage

So if I wanted to use this as a resource, so I could have it appear as part of a list, then what’s the key. Well, if the canvas itself is a resource, it will cause problems, but the canvas can be contained in other things, such as a DataTemplate for an ItemsControl.  I used this system in Shoppers Calculator to do the check marks, before I knew about the Opacity Mask trick.  Here’s the XAML I’m using:

<DataTemplate x:Key="ShoppingItemTemplate">
  <StackPanel>          
    <Grid MouseLeftButtonUp="ListItem_MouseUp" Background="{Binding SelectedBrush}" Height="30">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="6*"/>
        <ColumnDefinition Width="Auto"/>
      </Grid.ColumnDefinitions>     
      <TextBlock Text="{Binding Quantity}" FontSize="{StaticResource PhoneFontSizeMediumLarge}"/>      
      <TextBlock Grid.Column="1" Text="{Binding ValueString}" FontSize="{StaticResource PhoneFontSizeMediumLarge}" HorizontalAlignment="Right" Margin="6,0"/>
      <ContentControl Grid.Column="2" Visibility="{Binding ElementName=ControlContent, Path=DataContext.SupportsTax, Converter={StaticResource boolToVisible}}" MinWidth="30" VerticalAlignment="Bottom" VerticalContentAlignment="Bottom">
        <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Visibility="{Binding HasTax, Converter={StaticResource boolToVisible}}" Width="25.6875" Height="20.625" Clip="F1 M 0,0L 25.6875,0L 25.6875,20.625L 0,20.625L 0,0">
          <Canvas x:Name="Layer_1" Width="48.4111" Height="299.554" Canvas.Left="0" Canvas.Top="0">
           <Path x:Name="Path" Width="22.8125" Height="19.125" Canvas.Left="1.4375" Canvas.Top="1.5" Stretch="Fill" StrokeThickness="4" StrokeStartLineCap="Square" StrokeEndLineCap="Square" StrokeLineJoin="Bevel" Stroke="{StaticResource PhoneForegroundBrush}" Data="F1 M 3.4375,10.61L 10.8855,18.625L 22.25,3.5"/>
           <Path x:Name="Path_0" Width="18.75" Height="15.3125" Canvas.Left="3.3125" Canvas.Top="0" Stretch="Fill" StrokeMiterLimit="2.75" Stroke="#80000000" Data="F1 M 3.8125,7.625L 10.8125,14.8125L 21.5625,0.5"/>
           <Path x:Name="Path_1" Width="25.6875" Height="17.125" Canvas.Left="0" Canvas.Top="3.125" Stretch="Fill" StrokeLineJoin="Bevel" Stroke="#80000000" Data="F1 M 0.5,10.75L 9.1875,19.75L 12.875,19.5625L 25.1875,3.625"/>
         </Canvas>
        </Canvas>            
       </ContentControl>
     </Grid>
   </StackPanel>
 </DataTemplate>

This DataTemplate is used to display the shopping items in your basket in my Shoppers Calculator app.  The canvas represents an image (checkmark) that i’m using to denote if tax has been applied.  Yes, it’s a very simplistic image and example, but hopefully this has shown why I value Expression Design among my developer tools.

Posted in Development, Microsoft, Windows Phone | Tagged , , , | Leave a comment

Using app bar icons outside the app bar – how to get light / dark theming to work

The Windows Phone SDK provides a bunch of stock app bar icons and there are several other libraries. You can also make your own, by creating a white on transparent image in a png, at 76 x 76 pixels.

These icons when placed in the app bar show as white on a black background whn using the dark theme.  And when you switch to light, the icons switch too, to black on a white background.  However, try to use these icons outside the app bar and you don’t get that automatic theme switching for free. Switch to the light them and you’ll see a white icon on a white background just doesn’t show up.

Of course, if it’s a single static control, you can add both dark and light icons to your solution, name the control and throw a bit of code in the constructor for your page to check the theme and get the correct icon.

However, if your using the icon in a resource, such as a data template for a ListBox or ItemsControl bound to a collection, things are not so simple. This is because when you name something using x:name, it needs to be part of the view to be used in code behind, and can’t simply be a resource. One way to overcome this would be to use an event that fires each time an instance of that resource is being used. Another way is you could put the url in your view model, with some code in the getter to return the correct image, and then bind to that property. However, that’s the sort of thing we’re not supposed to have to do anymore, it kind of feels like a hack, especially the first.

So, what’s a better way?  After much searching I found the answer, here, in the forums on dev.windowsphone.com. Put it in a rectangle with a mask on it.  You only need one version of the icon and you can use this technique anywhere. The XAML I have here is adapted from that solution, which misses off sizing the rectangle.

<Rectangle Width="76" Height="76" Fill="{StaticResource PhoneForegroundBrush}">
    <Rectangle.OpacityMask>
        <ImageBrush ImageSource="/Assets/Icons/WhiteIcon.png" />
    </Rectangle.OpacityMask>
</Rectangle>

The OpacityMask is the key here.  Basically what we are saying is we want a rectangle, where the color will be PhoneForgroundColor (i.e. With on the dark theme and Black on the light theme).  The Opacity mask option uses a single brush and it’s the content of that brush that determines the outcome. Basically, the foreground color will show Everywhere the brush, in this case our icon, isn’t transparent. It doesn’t matter if the dark or light version of an icon is used for this, the result will be the same. As long as the rectangle is being filled with the color you want to show up, and the image (or other brush) you have here contains some transparent sections, you will get a shape forming.

And here’s the result applied to a rubbish / trash bin icon – it’s the normal delete icon in the Windows Phone 8 SDK (and a peak at what’s coming for Shoppers Calculator).

taxblack taxWhite

Posted in Development, How To, Microsoft, Silverlight, Windows Phone | Tagged , , | 1 Comment

How to create a custom scrolling list, which scrolls to newly added items.

So you want to show a scrollable list n screen but you don’t want to use a ListBox.  One reason for this might be because you want to take advantage of something lie width and Listbox dosn’t use up it’s full width.

Here’s the Shopping basket list from Shoppers calculated, done with a ListBox

LisBox

And here’s the same list done using the system below (no changes to the ItemTemplate). This illustrates one case where you might need to do this – for whatever reason, without specifying the pixel width of elements, the ListBox wouldn’t honor the way the grid was created, or put another way, ListBox items wouldn’t use the full space that they could, even if no size constraints are specified. However, in the example I’m giving you, the grid columns lined up with the headers I’d created for them.

scrollViewer

The simplest way is to use a ScrollViewer.  This allows any content places within it to be scrollable.  However, by itself this won’t scroll to the bottom to show newly added content each time you add something. It’s such a small, simple thing but was frustrating me when I was trying to figure this out for my app, so I thought this might be a good first development post.

So here’s the solution that will scroll properly to new items at the bottom, and allow you to customize the look of your list fully, using space properly, and not scroll back to the top or middle when you use your finger to scroll.

Firstly, the XAML:

<ScrollViewer x:Name="ScrollView">
    <ItemsControl ItemsSource="{Binding MyList}" SizeChanged="MyList_SizeChanged" ItemTemplate="{StaticResource MyTemplate}" />
</ScrollViewer>

We have the ScrollViewer which has been given a name to. Inside it is an items control, bound to a list which comes from a view-model.  There’s also a template, where we define how we want each item to look.  The last thing that’s there is an event handler for the SizeChanged event. Note that the even handler is on the ItemsControl and Not the ScrollViewer.

The event handler lives in the code-behind file.  Here it is:

private void MyList_SizeChanged(object sender, SizeChangedEventArgs e)        
{           
    ScrollView.ScrollToVerticalOffset(ScrollView.ExtentHeight);          
}

So the event handler has just one line, which moves the ScrollViewer bounds to show the bottom, where the new entry is likely to be. I’ll add a little more to this about how to make list item’s selectable for lists created in this manner sometime soon.

Posted in Development, Windows Phone | Tagged , , , , | Leave a comment

Becoming a real mobile developer, and a return to blogging

This site has been pretty quiet for a while now, but I will begin adding content here again soon. I’ve got my first app submitted to the Windows Phone app store and I’m hopeful that it will pass Microsoft’s testing and be published soon.

My work towards this target has meant in general I’ve been on a  bit of a blogging hiatus for a while but I really wanted to get something published.

So, yeah.. more to come, including some developer focused posts, with code samples and the like.

Microsoft Virtual Academy

In the meantime, I want to mention Microsoft Virtual Academy and their Windows Phone 8 JumpStart series.  These video tutorials run through a lot of information for budding Windows Phone developers, some obvious, but other bits are real nuggets of useful info that you might not otherwise come across or figure out until it was too late.

Andy Wigley and Rob Tiffany host it, and it’s broken down in to 20 parts which run between 30 minutes and 1 hour each.  There isn’t any self-assessment, but you can download the presentations and code snippets from some of the modules. While these videos are available through Channel 9, accessing them through the MVA makes them in to one continuous course, and can track your progress as you go through the videos.  They have now added an associated Exam – Pro: Designing and Developing Windows Phone Apps. So if you are looking for some training material around windows phone, this might be a decent place to start.

Building Apps for Windows Phone 8 Jump Start is here, and the Microsoft Virtual Academy is free.

Posted in Development, General | Tagged , , | Leave a comment

Why the Lumia 521 is right for T-Mobile

One of the smaller announcements during MWC was T-Mobile announcing it is picking up a variant of the Nokia Lumia 520, which will be the 521.  The 520 is Nokia’s new bottom-of-the-range smartphone so it’s somewhat surprising that T-Mobile USA would want that, especially compared to the higher spec and uni-body design of the Lumia 720, which was also announced during MWC.

 

T-Mobile has a few windows phones right now, but the standout ones are the Lumia 810 and the HTC Windows Phone 8X.  The Lumia 710 is a Windows Phone 7.5 device (T-Mobile branded devices won’t even be upgraded to 7.8).  The 810 and 8X have similarly specs in some ways, but crucially, both fall into the high end, or at least upper mid tier of the Windows Phone world.  In some ways, it’s desirable to see more of this, and perhaps people are disappointed that it’s the 520 and not the 720 that is coming, a device that has slightly lower spec’s than both the Lumia 810 and 8X but blows the 810 out of the water in the looks department, and is much more affordable than either of those.

However, T-Mobile announced earlier this year that it was dropping phone subsidies altogether and going 100% towards it’s current “Value plan” model in which you have cheaper calling plans but have to buy your phone outright or pay it off in installments.  The Lumia 521 should only differ from the standard 520 in supporting T-Mobiles 42Mbps HSPA+ network which uses 1700/2100Mhz bands. This means that customers should see a slim and sleek Windows Phone device, with a dual core processor, and it’s how much? Nokia suggest the device is about 140 Euro’s before taxes and subsidies, putting it close to $200. Many of the high end devices might start with a downpayment as high as that so this gives customers an affordable device option – something like $200 or $60 up front and $7/month for 20 months.

If T-Mobile is going to pull off the trick of dropping phone subsidies, it needs to stock a solid range of devices, including at mid and low prices and with the Lumia 810 and HTC 8X filling the upper-mid and high end of the spectrum, the 521 comes in at the lower-mid/low end.  And for a low end phone, what you will get is a smooth operating system that runs well on a dual-core processor with half a gig of ram, a 4″ screen, up to 42Mbps HSPA+ and it has a sleek design, and comes in a variety of colors. Once you get it home, you get to shove a 64Gb Micro SD card in it if you want and stuff it full of music or whatever else.

So when the day comes and T-Mobile switches over to it’s new pricing system, and the devices aren’t all something between free and $200 with a 2 year contract anymore, but their actual, full, retail price, users might fear that if they can’t afford the (I/m guessing here) $600 or $200 down and $20/month for 20 months for the iPhone 6, they have a good looking Windows Phone 8 device they can pick up and enjoy without sticker-shock.

You can read more about the Lumia 520 and 521 at Nokia Conversations.

Posted in General | Leave a comment