14

I am creating a dialog using MVVM which prompts the user to type in an http:// URL to a KML file. The "OK" button needs to be enabled when the URL is in the correct format, and it needs to be disabled when the URL is in an incorrect format.

Right now the button is bound to an ICommand, and the logic for CanExecute() looks like this:

return !string.IsNullOrEmpty(CustomUrl);

The command's CanExecuteChanged event is raised on every keystroke, and so far it's working well.

Now I want to do a little bit of actual validation. The only way I know to do that is as follows:

try
{
    var uri = new Uri(CustomUrl);
}
catch (UriFormatException)
{
    return false;
}

return true;

That's no bueno, especially since the validation is happening on each keystroke. I could make it so that the URI is validated when the user hits the OK button, but I'd rather not. Is there a better way to validate the URI other than catching exceptions?

Phil
  • 6,561
  • 4
  • 44
  • 69
  • 1
    Is it absolutely imperative that you run the validation once for every keystroke? Can you not just run validation when the OK button is clicked? – Kiley Naro Oct 24 '11 at 19:43
  • I could. But I like the user to know that the URL is invalid before moving the mouse and clicking the button. – Phil Oct 24 '11 at 19:44
  • 2
    Could you use [`Uri.TryCreate`](http://msdn.microsoft.com/en-us/library/system.uri.trycreate.aspx)? – George Duckett Oct 24 '11 at 19:45
  • 1
    So how about instead of checking every keystroke, you just put in a timer for 300ms or something and when the user has finished typing you run the validation? That way if they press multiple keys in a row you don't have to run the validation on every keystroke, but just once as soon as they pause. – Kiley Naro Oct 24 '11 at 19:45
  • I thought about that, though it might get a little hairy to do multithreaded user input/validation. Kind of like swatting a fly with a hammer. – Phil Oct 24 '11 at 19:49

5 Answers5

35

Yes - you can use the static method Uri.IsWellFormedUriString for this

return Uri.IsWellFormedUriString (CustomUrl, UriKind.Absolute);
Yahia
  • 69,653
  • 9
  • 115
  • 144
7

Possible solutions are two in my opinion:

  • Create a regular expression that checks URL correctness;
  • Use Uri.TryCreate method in order to avoid exceptions (if you don't need to create an Uri object you can use Uri.IsWellFormedUriString method);

I would prefer to use the second option, creating a correct RegEx could be difficult and could lead to many problems.

as-cii
  • 12,819
  • 4
  • 41
  • 43
1

You can add ValidationRules to the control and validation will be done "by magic".

Fischermaen
  • 12,238
  • 2
  • 39
  • 56
  • Could you point me to an article or documentation about ValidationRules? I've never used them. – Phil Oct 24 '11 at 19:47
  • Cool. I think with this approach I will still need to figure out a good way to detect a bad URI in C#. But this is still a nifty tool. – Phil Oct 24 '11 at 19:57
  • @Phil: Yes, you have still validate the value, but you won't need to do every keystroke. WPF will handle the need to validate for - validation is still your job. My answer was according to the last part of your question. – Fischermaen Oct 24 '11 at 20:02
0

You can just use Regex.IsMatch

And, here's a reliable pattern:

(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|(([^\s()<>]+|(([^\s()<>]+)))))+(?:(([^\s()<>]+|(([^\s()<>]+))))|[^\s`!()[]{};:'".,<>?«»“”‘’]))

scottm
  • 27,829
  • 22
  • 107
  • 159
0

Since you're already hooking into the keystroke event, you can use regular expression validation on the string, then it's up to you whether to flag it as invalid or not allow it at all. This post is similar and has the regular expression for a valid URI.

Community
  • 1
  • 1
philt5252
  • 939
  • 7
  • 19