I noticed that it is possible to bind variables of the type DateTime to a textbox in WPF. If I enter a wrong value it will not validate and show a red border.
How can I implement my own class, that I can bind to a textbox without having to bind to a property of the class? The Textbox should show a string and the class will validate the input.
Is this possible?
My current solution is this:
In the Model:
public string DefaultLanguageValue
{
get
{
return _defaultLanguageValue;
}
set
{
if (value != this._defaultLanguageValue)
{
ValidateLanguage(value);
this._defaultLanguageValue = value;
NotifyPropertyChanged();
}
}
}
private void ValidateLanguage(string value)
{
string rx = "([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*";
if (!Regex.IsMatch(value, rx))
{
throw new ArgumentException();
}
}
In the XAML:
<TextBox Text="{Binding TreeViewModel.Model.DefaultLanguageValue, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}" BorderThickness="0" MinWidth="100"/>
It would be nice to have a Class that I can just bind like a String, Int or DateTime for examlpe. Any Ideas?
You could bind to the Tag
property of the TextBox
itself and validate using a ValidationRule
:
public class DateValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (!DateTime.TryParse(value as string, out DateTime _))
return new ValidationResult(false, "Invalid date...");
return ValidationResult.ValidResult;
}
}
XAML:
<TextBox>
<TextBox.Text>
<Binding Path="Tag" RelativeSource="{RelativeSource Self}"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:DateValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
This doesn't require you to bind to a view model.
I finally tried the solution suggested by mm8.
The only issue I have now is that if one enters an invalid value into the textbox, it will not update the textbox when I programmatically change the value of the source after clicking a button.
I tried Validation after update, but this allows the user to save invalid values.
<TreeViewItem>
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<CheckBox x:Name="chkDefaultLanguage" IsChecked="{Binding TreeViewModel.TreeModel.DefaultLanguage, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="DefaultLanguage: " />
<TextBox BorderThickness="0" MinWidth="100">
<TextBox.Text>
<Binding Path="TreeViewModel.TreeModel.DefaultLanguageValue" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validationrules:LanguageCodeValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
class LanguageCodeValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
string rx = "([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*";
if (!Regex.IsMatch(value.ToString(), rx))
{
return new ValidationResult(false, "Invalid Language Codee.");
}
return ValidationResult.ValidResult;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.