ParseLib: A C# library for parsing values from a TextBox

Ready for inputs!(Note: I’ll come back to edit this post after I figure out how to properly format code for blog articles, and provide for downloadable sample code!)

It’s common to use a TextBox control for entering numbers, dates and other data types that are not actually textual in nature. In this article I’m going to introduce a general-purpose C# library to address this need — in a subsequent installment I’ll undertake to describe it’s use with specialized custom controls (such as the WPF ValueEditor control) that provide a more convenient method for data entry than a TextBox.

This library is usable within WPF, Silverlight, and ASP.NET 3.5. If you use InteMirror you can actually have just one source-code copy that is shared amongst all of the above platforms. But that’s a topic for another day.

Let’s start by introducing a common usage. For now, we’re simply going to consider one type of data – a number.

You have a TextBox, txtValue, and you want to assign your user enters to a variable (C# type Double) that you’ve named dValue. This is probably one of the most common approaches..

double dValue;
if (!Double.TryParse(txtValue.Text, out dValue))
{
  MessageBox.Show("Invalid Value", "CheapoApp: Oops!",
                  MessageBoxButton.OK, MessageBoxImage.Error);
  txtValue.Focus();
  txtValue.SelectAll();
}

Okay, so what’s wrong wid’at?

It works, but we can certainly improve upon it – if we care about designing a user-interface that is Good rather than just Passable. Here’re a few points to consider:

  1. You have to (or should) describe to your user what’s wrong with her input. But.. any code you put here to accomplish that, begs for being marshalled out into a reusable library.
  2. If you have other restrictions upon what the user can enter besides that it be a passable numeric value, you have to do additional checking here. Your simple “OK”-button event handler quickly becomes rather large.
  3. Your TryParse method will reject some perfectly understandable input, without telling your user why. What if she entered “one”, or “3/4”? Or, forgetting that she’s now in the US, entered “3.000,01” ?

This is such a common need in any application that it merits a bit of attention. Your users will appreciate consistency in your design, and explicit clear feedback for their mistakes. And they’ll appreciate that your software run without complaint, when what they entered should be perfectly comprehensible.

Now let’s do this same task using ParseLib.

ResultOfParseForNumber r = ParseLib.ParseForDecimal(txtValue, false);
if (r.IsOk)
{
  dValue = r.DecimalValue;
}
else
{
  r.Complain("the length");
}

A little more verbose than the previous, so let’s see what you’ve gained:

  1. The feedback to your user is clear and direct; which you don’t see any evidence of here because it all happens behind the scenes in your call to the Complain method. The actual code within ParseLib that achieves this is pretty sizeable. For example, if she entered “12X”, the call to Complain would say “the third character, “X”, is unexpected. Please enter a..”  Clear and specific.
  2. Complain uses your application-wide mechanism for showing feedback to your user, allowing for a consistent look and behavior (verbage, caption text, icons, etc).
  3. Via the additional parameters in the call to ParseForDecimal, you can place further restrictions upon the input that will be reflected in the call to Complain (if your user violated any of those expectations). In the example provided, you’ve disallowed negative values.
  4. If your user has entered “two”, or “1 1/2”, or “zero” or “none” or the letter ‘O’, your code now accepts that and interprets it correctly – with no coding on your part. If it can’t recognize the input, your call to r.Complain composes an appropriate clear explanation to show to your user.
  5. Your feedback to your user will be automatically globalized, assuming you also make provision for globalizing the string literal you use for “the length”  (topic for a later article!). The globalization of ParseLib is still a work in progress, but assuming it’s covered the languages and cultures you care about – you accomplish a lot by simply using this simple little class.
  6. This does not depend upon the throwing of exceptions to signal validation failure.
  7. You can supply either a string, or a TextBox (WPF, SilverLight, or ASP.NET) as the first parameter in your call to ParseForDecimal. The advantage of passing the actual TextBox instead of the string that it contains, is that the method can then as a minor convenience – upon validation failure – set focus to that TextBox and select it’s contents.

Still, if your user left the TextBox empty and that’s not okay, the response that r.Complain gives is rather generic. This is a common-enough scenario and the improvement provided by clear explanation is so great, that a separate method is provided for this. You could expand the above code with an additional branch, thus..

if (r.IsOk)
{
  dValue = r.DecimalValue;
}
else
{
  if (r.IsEmpty)
  {
    r.ComplainAboutEmptiness(“the length”,
       “You need to say what length you need, if you included X.”);
  }
  else
  {
    r.Complain(“the length”);
  }
}

This only scratches the surface at this point, and ParseLib is still a work in progress. I’d originally created it for online applications and then continued developing it as part of my work for several WPF desktop applications. It provides for the input of integers, real numbers, lower and upper limits, input of money, date, time, filesystem folder, filename, and email addresses. I can see a need for – and plan to later add – phone numbers, addresses, SSNs, and credit-card numbers. I’ll place it online for you to download, tinker with and use, and would appreciate your feedback on possible improvements. It’s already been a huge labor-saver, and anything that dramatically cuts down code-size and results in a better user-oriented design is something I consider well worth the investment.

Advertisements

About James W Hurst

a professional software designer since the beginning days of the desktop cptr and uC-controlled avionics, I today am focusing on Java, Swift, C# and F# for building mobile and desktop and online applications under Android, Xamarin.Forms, iOS, WPF, and ASP.NET-MVC along with the requisite HTML/CSS/JavaScript/Ajax for web applications. My database expertise has covered a panoply of different database-engines and modeling approaches, and my main area of academic interest is Artificial Intelligence and vision.
This entry was posted in C#, Software Design, WPF and tagged , , . Bookmark the permalink.

2 Responses to ParseLib: A C# library for parsing values from a TextBox

  1. AlexM says:

    I found your site on technorati and read a few of your other posts. Keep up the good work. I just added your RSS feed to my Google News Reader. Looking forward to reading more from you down the road!

  2. AlexM says:

    Your blog is interesting!

    Keep up the good work!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s