Restricting input on winform text boxes

How do you get a text box to only support positive floating point numbers on a Windows Form text box? (I know. I know. This is old school. However, it does pay the bills.)

One way that I thought was appealing was to implement the KeyDown event and control the key-presses; like this:

private void txtBowelMovementsPerDay_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
    // Allow numbers from keyboard
    if (e.KeyData >= Keys.D0 && e.KeyData <= Keys.D9)         return;     // Allow numbers from number pad     if (e.KeyData >= Keys.NumPad0 && e.KeyData <= Keys.NumPad9)
        return;

    // Allow periods from keyboard and number pad
    if (e.KeyData == Keys.Decimal || e.KeyData <= Keys.OemPeriod)
    {
        // but only one
        if (!txtBowelMovementsPerDay.Text.Contains('.'))
            return;
    }

    // Allow alt and shift to work
    if (e.Alt || e.Shift)
        return;

    // Allow the special keys to work
    switch (e.KeyData)
    {
        case Keys.End:
        case Keys.Enter:
        case Keys.Home:
        case Keys.Back:
        case Keys.Delete:
        case Keys.Escape:
        case Keys.Tab:
        case Keys.Left:
        case Keys.Right:
            return;
    }

    // Invalid input
    e.SuppressKeyPress = true;
    e.Handled = true;
}

A friend pointed out that while this was cool (ok, I may have change the tone there), it doesn’t internationalize well because a) it assumes the US keyboard layout and b) it assumes a ‘.’ is always the radix point. Bad, bad, bad.

Instead he turned me onto letting Windows do its job and checking the validity of the float to begin with and enabling the user to press “OK”. Like this…

private void txtBowelMovementsPerDay_TextChanged(object sender, EventArgs e)
{
    btnOk.Enabled = TrackSpacingMicronsTextBoxIsValid();
}

private bool TrackSpacingMicronsTextBoxIsValid()
{
    float trackSpacingMicrons;

    // is it a valid float?
    if (float.TryParse(txtBowelMovementsPerDay.Text, out trackSpacingMicrons))
    {
        // is it a positive number?
        if (trackSpacingMicrons <= 0)
            return false;
        return true;
    }
    else
        return false;
}

This is a much better approach and facilitates i18n. While Winforms is old-school, the problem is nicely solved in WPF.

<TextBox Name="txtBowelMovementsPerDay" TextWrapping="Wrap" Text="{Binding Path=BowelMovementsPerDay, Mode=TwoWay, 
    UpdateSourceTrigger=PropertyChanged,StringFormat={}{##.##}}"></TextBox>

For systems where you must make a decision to validate or preempt keystrokes, validation will always be best. By validation, I mean that you do not let the user continue unless all the data is correct. This is true with web page development as well as Javascript will parse floats based on locale.

Stupid Simple File Server from Spare Parts

Another installment of things I like because the just work.

I frequently have the need to spin up a file server, either for temporary use or for longer term storage.
Recently I was migrating a system from one place to another and needed a large amount of fast temporary storage.
At home I have a file server for mass storage of music, videos etc.

There are lots of solutions to this. Could always just use an old Win XP box, or set up a Linux server using your favorite distro. Then there are free software systems, FreeNAS is a good example.

One I like is Server Elements.
They have a line of products including one that boots from a floppy! Hardware requirements for all of the products are very modest. Basically take some old PC, stuff it full of old disks, create a bootable CD, or Thumb Drive and off you go. Prices range from $10 – $35 for the 64bit product with some media streaming capabilities.

For quick set up – Server Elements is really great and worth the small price.
If you want more features, FreeNAS is a very good choice.

Here is an excellent article on the topic.
http://www.smbitjournal.com/2012/04/choosing-an-open-storage-operating-system/

Swiss Army Knife of SMTP Servers

Just wanted to give a shout out to my favorite SMTP Server.
When you find yourself needing a robust, easy to configure and support SMTP IMAP/ POP3 server that can handle about any messaging need you could think of … check out MDaemon from the folks at Alt-N Technologies.

How good is it? Well, not that long ago, Research In Motion (RIM), you know, the BlackBerry people, bought? the company.
(not positive about the change in ownership as I don’t work for the company)
During this time BlackBerry support was added. Then the market turned, and Alt-N became independent again.

I’ve been using MDaemon for many years now in several environments. I’ve tried others, but keep going back to this one. It just works. Rarely do I find a messaging problem that it doesn’t handle. You *nix fans will even like it. Although it runs on Windows machines, it has a *nix feel to it as everything is kept in files.

beans

Simple Python JSON server based on jsonrpclib

I needed a simple python JSON server executing in its own thread but that was easily extensible.   Let’s get right to the base class code (or super class for those who build down).

#! /usr/bin/python

import threading

import jsonrpclib
import jsonrpclib.SimpleJSONRPCServer

class JsonServerThread (threading.Thread):
  def __init__(self, host, port):
    threading.Thread.__init__(self)
    self.daemon = True
    self.stopServer = False
    self.host = host
    self.port = port
    self.server = None

  def _ping(self):
    pass

  def stop(self):
    self.stopServer = True
    jsonrpclib.Server("http://" + str(self.host) + ":" + str(self.port))._ping()
    self.join()

  def run(self):
    self.server = jsonrpclib.SimpleJSONRPCServer.SimpleJSONRPCServer((self.host, self.port))
    self.server.logRequests = False
    self.server.register_function(self._ping)

    self.addMethods()

    while not self.stopServer:
      self.server.handle_request()
    self.server = None

  # defined class definitions

  def addMethods(self):
    pass

So the idea is simple,   Derive a new class from this and implement the addMethods method and the methods themselves.

#! /usr/bin/python

import jsonServer

class JsonInterface(jsonServer.JsonServerThread):
  def __init__(self, host, port):
    jsonServer.JsonServerThread.__init__(self, host, port)
    self.directory = directory

  def addMethods(self):
    self.server.register_function(self.doOneThing)
    self.server.register_function(self.doAnother)

  def doOneThing(self, obj):
    return obj

  def doAnother(self):
    return "why am I doing something else?"

In the derived class, implement the methods and register them in addMethods.  That is all.  Now we can worry simply about implementation.  Be aware of any threading synchronization of exception handling.  Jsonrpclib takes care of exception handling as well and converts it into a JSON exception.

One last item of note.  In the base class, the stop method is interesting.  Since handle_request() is a blocking call in the thread, we need to set the “stop” flag and make a simple request.  The _ping method does this for us.  Then we join on the thread waiting for it to end gracefully.

The jsonrpclib is a very useful library and well done.  By the way, this example is for Python 2.7.  On Ubuntu 14.04, you can install this using “apt-get install python-jsonrpclib”.