0

I have error validation in my viewModel, such that when the UserName is not at least 2 characters long, it will have a validation error.

When my application starts up, this field is not validated and is considered to have no errors. It is only when the setter is called, does it check if the input is valid. In my form, this has the result that upon load there is no red box around the TextBox. However, as soon as the user types in a character, the UserName setter is called and it sees that the length is less than 2 characters, and as such has a validation error.

This is how it works by default, and this is what I want. I don't want to start off with the form open and having unwelcoming red boxes around the TextBox.

Now, on this form, I have a button that is tied to an ICommand. When the forum loads up, because the UserName field is technically not considered to have any errors, the button is enabled. However, when the user enters one character, it turns to disabled, and if he deletes everything it'll remain disabled as it should.

I want my form to load without any errors, but to have the button be disabled.

Now, my CanExecute() method is checking on a field I Have in my ViewModel which basically checks to see if the errors list count is greater than 0. If it is, it has errors and thus returns true. If not, it returns false.

I have a way to solve my above dilemma, but I do not like it. I have a check as such.

return UserName.Length < 2 || errors.Count > 0

Now this seems fine, but if I have a lot more fields that are being checked, such as Address and Port, I have to add these as well. All this really serves to do is provide this initial false for the CanExeute(), and it's useless at all other times, because it will be redundant. If the UserName.Length < 2, of course the errors. array will have some errors in it.

It would be nice, is if creating my ICommand, which in this case is a DelegateCommand from Prism, I can initialize it to be false and thus disabled.

Cowman
  • 678
  • 7
  • 25
  • Did you try update on lost focus – paparazzo Jan 17 '13 at 20:06
  • Update on lost focus? Do you mean updating the binding on a lost focus, instead of each keystroke? As far as I can tell, that doesn't really help my problem. – Cowman Jan 17 '13 at 21:35
  • Really not throwing an error with length < 2 while it has focus does help your problem? – paparazzo Jan 17 '13 at 22:27
  • Set up a bool value to represent `pageLoading`. After your Initialization is complete, change `pageLoading` to false, and you should be able to check this variable in your `canExecute` method. – Zack Jan 17 '13 at 23:11
  • I do really wish there was a built in way to do this with commands... starting disabled... since creating an entire variable or check just to deal with this loading cause and have it run it every time after creation just seems silly to me. – Cowman Jan 17 '13 at 23:59

1 Answers1

-1

It sounds like all you should have to do is force the "CanExecute" of the command when it starts to ensure it is looking at most recent "criteria".

Since the interface requires the declaration of an event handler via

public event EventHandler CanExecuteChanged;

I'm sure you have something in your ICommand handler class such as

public void RaiseCanExecuteChanged()
{
    if (CanExecuteChanged != null)
        CanExecuteChanged(this, new EventArgs());
}

That said, in the startup of your view model where you have your ICommand object references instantiated, I would just

yourICommandButton.RaiseCanExecuteChanged();

This will force the check of the event and refresh itself as enabled or not before even the first keystroke in the field.

Clarification... Although I mention "button", I know there is no actual "button" in the view model, but an ICommand object that HANDLES the button's action via the Execute/CanExecute bindings.

As for refreshing the "red" border, that should NOT happen when you are just asking the ICommand handler to "RaiseCanExecuteChanged". If the "CanExecute" function returns FALSE, it will be disabled for the user...

public bool CanUserClickMe()
{
   return UserName.Length > 1 && errors.Count == 0;
}

This is not actually calling the validation tests against any explicit fields, just looking at the properties the person already has available to work with. If the user's name is not at least the two characters, it will return FALSE and thus disable the button ASSOCIATED to the ICommand object.

DRapp
  • 47,638
  • 12
  • 72
  • 142
  • This will cause the text box to load up with a red border because it is not "valid" since it contains less than 2 characters. – Zack Jan 17 '13 at 19:10
  • Why is the word "Button" present in this answer? we're talking about ViewModels, not Views. "Button" is an unknown concept from the ViewModel's perspective. – Federico Berasategui Jan 17 '13 at 19:11
  • @ZackT., it shouldnt as I would not be forcing the change value of the textbox, just CHECKING what its value IS. See revised clarification. – DRapp Jan 17 '13 at 19:23
  • @HighCore, revised clarification... as originally posted, he had a button on his VIEW that was linked to an "ICommand" instance. That was why I originally commented as I did. – DRapp Jan 17 '13 at 19:24
  • When I say red border, I'm referring to the text box. The text box gets a red border applied due to the validation errors. When my application starts, there are technically no errors, even though the fields are blank. This is because the error checking does not start until the setters are first called(text being changed). This is ideal, as it prevents me from having a fresh screen with red error borders. This also means however, that my ICOmmand can call it's CanExecute and will return true, because there are no errors. That's why I mentioned I have to put in check if the field is empty. – Cowman Jan 17 '13 at 21:33