WPF表单验证
利用Validator.TryValidateProperty方法以及IDataErrorInfo实现
XML代码如下
<Grid> <Slider VerticalAlignment="Bottom" Minimum="0" Maximum="1000" Name="slider" Value="10"></Slider> <TextBox Height="30" Width="150" Name="tex" Validation.ErrorTemplate="{StaticResource ErrorTemplate}"> <!--Validation.Error="tbx1_Error"--> <TextBox.Text> <Binding ElementName="slider" Path="Value" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> <Binding.ValidationRules> <local:CustomValidationRule ValidatesOnTargetUpdated="True"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox Height="30" Width="150" Margin="0,100,0,0"> <i:Interaction.Behaviors> <local:TextBoxWatermarkBehavior Watermark="11111"/> </i:Interaction.Behaviors> </TextBox> </Grid>
样式如下
<ControlTemplate x:Key="ErrorTemplate"> <DockPanel> <TextBlock DockPanel.Dock="Bottom" Foreground="Red" FontSize="10" Text="{Binding ElementName=adornedElementName, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"/> <Border BorderBrush="Red" BorderThickness="0.5"> <AdornedElementPlaceholder Name="adornedElementName"/> </Border> <!--<Border BorderBrush="Red" BorderThickness="1"> <AdornedElementPlaceholder Name="adornedElementName"> </AdornedElementPlaceholder> </Border>--> </DockPanel> </ControlTemplate>
C#代码
public class ValidateModelBase:NotifyBase, IDataErrorInfo { public ValidateModelBase() { } #region 属性 /// <summary> /// 表当验证错误集合 /// </summary> public Dictionary<string, string> dataErrors = new Dictionary<string, string>(); /// <summary> /// 是否验证通过 /// </summary> public bool IsValidated { get { if (dataErrors != null && dataErrors.Count > 0) { return false; } return true; } } #endregion public string this[string columnName] { get { ValidationContext vc = new ValidationContext(this, null, null); vc.MemberName = columnName; var res = new List<System.ComponentModel.DataAnnotations.ValidationResult>(); var result = Validator.TryValidateProperty(this.GetType().GetProperty(columnName).GetValue(this, null), vc, res); if (res.Count > 0) { string errorInfo = string.Join(Environment.NewLine, res.Select(r => r.ErrorMessage).ToArray()); AddDic(dataErrors, columnName, errorInfo); return errorInfo; } RemoveDic(dataErrors, columnName); return null; } } public string Error { get { return null; } } #region 附属方法 /// <summary> /// 移除字典 /// </summary> /// <param name="dics"></param> /// <param name="dicKey"></param> private void RemoveDic(Dictionary<string, string> dics, string dicKey) { dics.Remove(dicKey); } /// <summary> /// 添加字典 /// </summary> /// <param name="dics"></param> /// <param name="dicKey"></param> private void AddDic(Dictionary<string, string> dics, string dicKey, string dicValue) { if (!dics.ContainsKey(dicKey)) dics.Add(dicKey, dicValue); } #endregion }
NotifyBase如下实现INotifyPropertyChanged接口
public class NotifyBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public void SetProperty<T>(ref T feild, T value, [CallerMemberName] string propName = "")
{
feild = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
UserModel实体类如下
public class UserModel : ValidateModelBase
{
private string userName;
[Required(ErrorMessage = "用户名不可为空")]
public string UserName
{
get { return userName; }
set { userName = value; SetProperty(ref userName,value); }
}
private string userAge;
[Required(ErrorMessage = "年龄不可为空")]
[Range(0, 100, ErrorMessage = "年龄范围为0~100")]
public string UserAge
{
get { return userAge; }
set { userAge = value; SetProperty(ref userAge, value); }
}
private bool isFormValid;
public bool IsFormValid
{
get { return isFormValid; }
set { isFormValid = value; SetProperty(ref isFormValid, value); }
}
}

浙公网安备 33010602011771号