Implementing numerical InputBox in Windows Phone
This article shows how to implement a numerical input box, which handles negative/ positive integers as well as float values, in WP8 applications.
Article Metadata
Code Example
Tested with
Compatibility
Article
Contents |
Introduction
In general you can implement numerical InputBox for WP8 by simply defining the InputScope to be Number. This gives you a keyboard with numerical characters as well as the minus sign and decimal separators. This implementation of an InputBox does not give options to do any other filtering.
This article illustrates a simplified way on doing input filtering such that the InputBox can be handled for both negative and positive integers as well as float values. This article also illustrates a simple way of showing a valid range. Such an InputBox is very useful in certain scenarios - for example while providing a latitude or a longitude as an input, as shown below.
The example in this article has been implemented in several Map examples available in the Windows Phone 8 Maps Examples project.
Generally, to get the input to work as expected, you need to:
- Implement NumberInputBox the class
- Include the namespace in your xaml file
- Use the NumberInputBox just as you would use normal textboxes
Implementing the NumberInputBox class
To include new class into a project, you would simply right click the project, select Add->New item from the pop-up menu and then select Class from the list and give the class a meaningful name.
As we simply want to make InputBox, we get it done lot easier by reusing the already available implementations. Thus, we derive a new class from TextBox as shown below.
public class NumberInputBox : TextBox
To enable different types of input, we define an enumeration which accounts for available input types, as shown below.
public enum InputType
{
Integer = 0,
IntegerPositive = 1,
Float = 2,
FloatPositive = 3,
}
We then define an internal variable for which we can set the input type into. Also, we have internal variables for limiting the values for a valid input, as well as a Boolean variable which indicates whether the current input is in the defined range.
public InputType Type { get; set; }
public int MaxValue { get; set; }
public int MinValue { get; set; }
public bool ValueOk { get; set; }
We can then implement the constructor for the class. Inside the constructor, we will need to set the input scope to make sure we get right keyboard for the input, as well as we need to set the callback for the TextChanged event. Which after we simply set default values for the internal variables, so to make sure that they are always valid.
Then the actual filtering of the input happens inside the TextChangedEvent function. Inside the function, we simply take the current input, put it through our own parser, and then set it back to the visible text. After setting the value, we check whether we have max/min values set, and if they are we check the input range and use colour to indicate whether the value is within the defined range.
private void TextChangedEvent(object sender, TextChangedEventArgs e)
{
this.Text = ParseDouble(this.Text);
this.SelectionStart = this.Text.Length;
if (this.MaxValue != this.MinValue)
{
double d;
if (double.TryParse(this.Text, out d))
{
if (d < this.MinValue || d > this.MaxValue)
{
this.ValueOk = false;
this.Foreground = new SolidColorBrush(Colors.Red);
}
else
{
this.ValueOk = true;
this.Foreground = new SolidColorBrush(Colors.Black);
}
}
}
}
The parsing code is really simple. It basically takes the whole input buffer and removes any characters which are not allowed. After which it returns the string which is only having allowed input characters. The buffer is simple looped through in for loop from first character until the last.
In each loop, first in the validations the first character is checked whether it contains minus sign, and this character is only allowed to be the first character, in any other place it will be ignored. Also if only positive input is allowed, then no minus sign is accepted in any position.
The second check is accepting any digit-characters at any position of the buffer.
If the number input is in float mode, then the last check is allowing the buffer to contain single instance of decimal separator. Note that the decimal separator used inside the code depends on the locale used, the UI default separator might not match the one required by the code. Thus, with this check both dot and comma characters are allowed however the returned buffer will only contain the decimal separator for the current locale.
String ParseDouble(string input)
{
if (input.Length > 0)
{
String outBut = "";
bool foundSeparator = false;
for (int i = 0; i < input.Length; i++)
{
if ((this.Type == NumberInputBox.InputType.Integer
|| this.Type == NumberInputBox.InputType.Float)
&& ((i == 0) && input[0] == '-'))
{
outBut = outBut + input[i];
}
else if ((input[i] >= '0' && input[i] <= '9'))
{
outBut = outBut + input[i];
}
else if (this.Type == NumberInputBox.InputType.Float
|| this.Type == NumberInputBox.InputType.FloatPositive)
{
if (foundSeparator == false)
{
string Sepa = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
if (Sepa.Length > 0)
{
if (Sepa[0] == input[i] || '.' == input[i] || ',' == input[i])
{
outBut = outBut + Sepa[0];
foundSeparator = true;
}
}
}
}
}
return outBut;
}
else
{
return "";
}
}
Adding NumberInputBox to your XAML
First you need to add the namespace to your XAML file. For e.g. if the class is defined under the AreaSelector namespace, then simple add following text into the header section of the XAML file.
xmlns:myns="clr-namespace:AreaSelector"
Then to use the control, instead of using textbox tags you would be using myns:NumberInputBox tags instead. For example, if you wish to have input boxes for latitude and longitude values, you could do it as follows:
<myns:NumberInputBox x:Name="LatitudeBox" Type="Float" MaxValue="90" MinValue="-90"/>
<myns:NumberInputBox x:Name="LongittudeBox" Type="Float" MaxValue="180" MinValue="-180"/>
Summary
This article showed how to implement a numerical InputBox in WP8 applications. Such an InputBox may be useful for accepting input values such as latitude or longitude values.


Contents
Croozeus - Sub-edited
Hi Jukka,
Useful article!
I sub-edited the article and improved the readability, please check if OK: http://www.developer.nokia.com/Community/Wiki/index.php?title=Implementing_numerical_inputbox&action=historysubmit&diff=184367&oldid=184348
I think it's useful that you've pointed to a sample project that implements this. Even better would be attaching class file that can be readily usable.
Regards
Pankaj.croozeus 17:21, 6 March 2013 (EET)
Aady - This will be compatible with wp7 as well right?
Correct me if i am wrong on that, or is any specific functionality shown by you is only available in WP8 and not in Wp7.5. And if its compatible with wp7 you might want to change the intro and add wp7.5 in category.
Regards,
AadyAady 19:58, 6 March 2013 (EET)
Symbianyucca -
Pankaj: I actually would want to keep the full code in the project only, that way its easier to update, and there would be less chance on having old version, if something needs to be changed.
aady: I would not see any problems on using it with WP7, basically I was working on WP8 maps API (not compatible with WP7) when I felt need for this item, so made it for it, and never got to testing it with WP7. Anyway, if you have tried with WP7, please let us know how it works in there as well.symbianyucca 22:09, 6 March 2013 (EET)
Hamishwillee - Minor subedit
Hi Jukka
Looks good to me. I did a minor further subedit and also added link in the ArticleMetaData to your actual source file in the Maps project.
FYI: We usually ask for source code in buildable project because this makes it easy to very that the code works, allows re-users to avoid copy-paste errors, and also gives us a compatibility point where we know the code worked. As your project is "living", simply linking to the source file as I have done above should be sufficient.
With respect to WP7.5 we'll normally tag with that category (as has been done) if there is no obvious reason it wouldn't work. However in the ArticleMetaData we take care to ensure that we list what we know it has been tested against (only)
Would be great if you could add what devices you've tested this against.
Thank you for this.
Regards
Hamishhamishwillee 07:10, 18 March 2013 (EET)