I'm trying to achieve validation on button click for a textbox using binding. Basically when I click Submit my textbox is not turning red and giving me the "Required" error, it is when I add text to it.
I'm new at validation and been looking at this for almost a week on and off in frustration. I think my answer may have something to-do with propertychangedevent? but I'm not sure and resorting to asking the professionals.
All and any help with this will be must appreciated.
Here is my Model class:
public class sForms : INotifyPropertyChanged, IDataErrorInfo
{
private string name;
public string NAME { get { return name; } set { if (name != value) name = value.Trim(); OnPropertyChanged("NAME"); } }
public string this[string columnName]
{
get
{
return ValidationError(columnName);
}
}
public string Error { get { return null; } }
private string ValidationError(string columnName)
{
string error = null;
switch (columnName)
{
case "NAME":
error = IsNameValid();
break;
}
return
error;
}
static readonly string[] ValidatedProperties = { "NAME" };
public bool IsValid
{
get
{
foreach (string property in ValidatedProperties)
{
if (ValidationError(property) != null)
{
return
false;
}
}
return
true;
}
}
public string IsNameValid()
{
if (string.IsNullOrWhiteSpace(NAME) || string.IsNullOrEmpty(NAME))
return "Required";
else
return
null;
}
#region Property Changed
private void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
Here is my XAML for my button + Text Box;
<TextBox Controls:TextBoxHelper.UseFloatingWatermark="True"
Controls:TextBoxHelper.Watermark="Name *"
Grid.Column="1" Grid.Row="1"
Margin="0 0 2 0"
Text="{Binding Path=NAME, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
>
<Button Content="Submit"
Style="{DynamicResource SquareButtonStyle}"
VerticalAlignment="Bottom" HorizontalAlignment="Right"
Margin="0 0 10 0"
Click="Submit_Click"
/>
Here is my code behind;
public v_subsForm()
{
InitializeComponent();
this.DataContext = subs;
}
sForms subs = new sForms();
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
private void Submit_Click(object sender, RoutedEventArgs e)
{
if (subs.IsValid)
MessageBox.Show("True");
else
MessageBox.Show("False");
}
First, your code works as it should, assuming you included all
MahApps.Metroresources that are required. Also, you don't need to implementINotifyPropertyChangedin your code-behind (that's your MainWindow I guess).That is not how
IDataErrorInfoworks.IDataErrorInfodefines an API that the binding can query for errors on the object that it's bound to. So, when yourNAMEproperty is changed, the binding will query the indexer on yoursFormsobject:subs["NAME"]. If it gets an error, error template is applied. This is usually paired with a submit button whoseCommandproperty is bound to a command whoseCanExecutechecks for errors and if there are errors the button is disabled (so you can not submit if there are errors, button is disabled).If you want to do your validation on button click, you don't need to implement
IDataErrorInfo.System.Windows.Controls.Validationclass has attached properties that drive presentation of errors:HasError,Errors,ErrorTemplate. But you can't just setValidation.HasErrorto true (there is no accessible setter) like you can setValidation.ErrorTemplate. To setValidation.HasErrorin code-behind, you can useValidation.MarkInvalidmethod, but this is not how these things are usually done. Here is a quick example, for this to work you need to setNameproperty on yourTextBoxto MyTextBox:So if
MyTextBox.Textis empty, it will be considered invalid.