Just a quick follow up:
Martin's solution should work if your MinValue = 0. If your MinValue is larger than 0 (as mine was) then an infinite loop is created as .clear() fires the OnError event again - perhaps internally .clear() sets to a value to zero, I dunno.
Anyway, the way I got round this was to extend the RadNumericTextBox class and add two properties of my own: customMin and customMax. Setting these properties now writes two HiddenFields to the page and those hidden fields can be accessed via JS to check the value entered is within the range. Not setting the built-in MinValue and MaxValue properties gets around the value being reverted to MinValue/MaxValue if you go over or under.
I'd like to suggest a property that allows you to specify how values are handled by RadNumericTextBox if they're outside of your specified range. Perhaps: clear textbox | preserve user's entered number | revert to min/max value.
Cheers,
Adam