Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I disable a WPF dialogue OK button in response to invalid input determined by a custom ValidationRule class?
    primarykey
    data
    text
    <p>I have a simple WPF dialogue allowing the user to enter a name. We are using a Mvvm approach without any code-behind files. I need to validate the input and only enable the OK button when the input is valid. I am currently doing the validation using a custom error template in my view and a custom implementation of the ValidationRule class.</p> <p>The text box in the dialogue is defined as:</p> <pre><code> &lt;TextBox Width="250" Height="25" Margin="5" Validation.ErrorTemplate="{StaticResource customErrorTemplate}"&gt; &lt;TextBox.Text&gt; &lt;Binding Path="WitnessName" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"&gt; &lt;Binding.ValidationRules&gt; &lt;ValidationRules:NameRule /&gt; &lt;/Binding.ValidationRules&gt; &lt;/Binding&gt; &lt;/TextBox.Text&gt; &lt;/TextBox&gt; </code></pre> <p>The NameRule is defined as:</p> <pre><code>public class NameRule : ValidationRule { public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { var isValid = (value as string == null) || Regex.IsMatch(value.ToString(), @"^[\p{L} \.'\-]+$"); return new ValidationResult(isValid, "Name can contain only letters, apostrophes and hyphens."); } } </code></pre> <p>The OK button IsEnabled property is bound to an IsOkEnabled property on the view model, which is only true when the input is valid.</p> <pre><code>&lt;Button Name="OnOkClick" Margin="5" IsEnabled="{Binding IsOkEnabled}"&gt;OK&lt;/Button&gt; </code></pre> <p>The IsOkEnabled property is updated in response to a change in the WitnessName text by monitoring the WitnessName PropertyChanged event.</p> <pre><code>public string WitnessName { get { return this.witnessName; } set { this.witnessName = value; this.NotifyOfPropertyChange(() =&gt; this.IsOkEnabled); } } </code></pre> <p>The problem is that with the validation operating in the view the PropertyChanged event isn't being fired on the vew model when invalid input is entered, so the IsOkEnabled property isn't being updated and the OK button remains enabled.</p> <p>Is there a way of forcing the update on the IsOkEnabled property in response to a even invalid input on my current implementation?</p> <p>I have looked at both <a href="http://karlshifflett.wordpress.com/mvvm/input-validation-ui-exceptions-model-validation-errors/" rel="nofollow">Karl Shifflet's</a> and <a href="http://joshsmithonwpf.wordpress.com/2008/11/14/using-a-viewmodel-to-provide-meaningful-validation-error-messages/" rel="nofollow">Josh Smith's</a> suggestions but neither uses (as far as I can tell) a view error template and I'd like to use one to provide the visual feedback.</p> <p><strong>Update: Trying this with a bound ICommand as suggested by Danny</strong></p> <p>I have tried this by creating a VM specific to the OK button, which implements ICommand. The OkButtonViewModel has a property to hold the dialogue VM (set by IoC and unity) and the CanExecute and Execute implementations refer to the relevant properties/methods on this VM.</p> <p>In OkButtonViewModel:</p> <pre><code>public bool CanExecute(object parameter) { return this.witnessDialogue.IsValid; } public void Execute(object parameter) { this.witnessDialogue.OnOkClick(); } </code></pre> <p>How do I bind my button to this VM rather than the dialogueVM? I can do it if the OkButtonViewModel is a property on the dialogue VM but not when the dependence is this other way around, which it needs to be for the button to be able to use the implementations on the dialogue VM.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload