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接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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实体类如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)