Property binding is not updated when ValidationRule Fails

I have several text boxes for input fields and a Save button in my opinion. Two of the text boxes are required fields to save, and I've set up a custom ValidationRule in the xaml for some visual feedback (red borders and tooltips):

<TextBox ToolTip="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}">
    <TextBox.Text>
        <Binding Path="ScriptFileMap" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <v:MinimumStringLengthRule MinimumLength="1" ErrorMessage="Map is required for saving." />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

      

The Save button is associated with a delegate that calls the SaveScript () function. The function does not allow the user to save if the properties of two required fields are empty:

public void SaveScript()
{
    if (this.ScriptFileName.Length > 0 && this.ScriptFileMap.Length > 0)
    {
        // save function logic
    }
}

      

However, the function still allows you to save the file. Upon closer inspection, I see that the values โ€‹โ€‹of these two fields (ScriptFileName and ScriptFileMap) are not updated when the ValidationRule fails and it goes by the last known value.

Is this the expected behavior for the ValidationRule or am I missing something or is something crashing? If the former, is there a way to reverse this behavior? I cannot prevent saving to the ViewModel if an empty string is never passed to the bound property.

+3


source to share


3 answers


Since I never worked on handling ValidationRule, I took a different approach and just used multiple bindings. Here's my textbox with links for text, border and tooltip:

<TextBox Text="{Binding Path=ScriptFileName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" BorderBrush="{Binding Path=ScriptFileNameBorder, UpdateSourceTrigger=PropertyChanged}" ToolTip="{Binding Path=ScriptFileNameToolTip, UpdateSourceTrigger=PropertyChanged}" />

      

Here's my binding for the textbox, with logic to update the border and tooltip (no validation):



public string ScriptFileName
        {
            get
            {
                return this.scriptFileName;
            }

            set
            {
                this.scriptFileName = value;
                RaisePropertyChanged(() => ScriptFileName);

                if (this.ScriptFileName.Length > 0)
                {
                    this.ScriptFileNameBorder = borderBrushNormal;
                    this.scriptFileNameToolTip.Content = "Enter the name of the file.";
                }
                else
                {
                    this.ScriptFileNameBorder = Brushes.Red;
                    this.scriptFileNameToolTip.Content = "File name is required for saving.";
                }
            }
        }

      

Doing it this way allows me to have the user feedback I want (red borders and tooltip) when the field is blank and still uses the code in my SaveScript function to prevent the Save button from being pressed.

This is a bit more typing since then I need to have separate properties for each additional field I want to make necessary, but everything else I've tried either had no effect or broke something else in the program (including ValidationRules and DataTriggers).

+1


source


Yes, this is expected behavior. By default, validation rules are executed on the raw suggested value, that is, before it is converted and written back to the binding source.



Try changing ValidationStep

on your rule to UpdatedValue

. This should make the rule work after the new value is converted and written back.

+6


source


You should implement the CanExecute

and method RaiseCanExecuteChanged

that will disable your button until all the required properties have passed the validation logic.

+3


source







All Articles