WPF 使用绑定验证实现输入验证通过后才可提交
参考
- deepseek
- 豆包
- copilot
- https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/data/how-to-implement-binding-validation
- https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.controls.validation.errortemplate?view=windowsdesktop-9.0
- https://cloud.tencent.com/developer/ask/sof/111142093
- https://cloud.tencent.com/developer/ask/sof/108693498
- https://dev59.com/iFPTa4cB1Zd3GeqPhTp3
- https://stackoverflow.org.cn/questions/4635716
环境
| 软件/系统 | 版本 | 说明 | 
|---|---|---|
| Windows | windows 10 专业版 22H2 64 位操作系统, 基于 x64 的处理器 | |
| Microsoft Visual Studio | Community 2022 (64 位) - Current 版本 17.14.9 | |
| Prism Template Pack | 2.4.1 | Microsoft Visual Studio 扩展 | 
| .NET | 6 | |
| Prism.Unity | 8.1.97 | nuget依赖库(使用 Prism Template Pack 创建项目时选择的容器,使用模板创建的项目自动安装) | 
| MaterialDesignThemes | 5.2.1 | nuget依赖库 | 
正文
步骤
- 实现 AccountLoginValidationRule.cs
- Login.xaml 页面附加属性类的命名空间 xmlns:validationRule="clr-namespace:WPFNetConnect.ValidationRules"
- 在控件中使用<TextBox x:Name="LoginAccountTextBox" Style="{StaticResource LoginAccountTextBox}"> <Binding Path="Account"> <Binding.ValidationRules> <!-- 可以带参数,可以多条条件 --> <!-- validationRule:AccountLoginValidationRule Min="2" / --> <!-- validationRule:AccountLoginValidationRule Min="2" Max="10" / --> <validationRule:AccountLoginValidationRule /> </Binding.ValidationRules> </Binding> </TextBox>
- 提交命令在创建时,也要编写 CanExecute逻辑,否则首次初始化,绑定验证默认为True,导致提交按钮可用
主要代码
- AccountLoginValidationRule.csusing System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Security.Principal; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Input; // https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/data/how-to-implement-binding-validation namespace WPFNetConnect.ValidationRules { class AccountLoginValidationRule : ValidationRule { /// <summary> /// 最短长度 /// </summary> public byte Min { get; set; } = 8; /// <summary> /// 最大长度 /// </summary> public byte Max { get; set; } = 16; public override ValidationResult Validate(object value, CultureInfo cultureInfo) { var val = value as string; if (string.IsNullOrEmpty(val)) { return new ValidationResult(false, "请输入正确的账号"); } if (val.Length < Min || val.Length > Max) { return new ValidationResult(false, "请输入正确的账号"); } return ValidationResult.ValidResult; } } }
- Login.xaml<Window x:Class="WPFNetConnect.Views.Login" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:helper="clr-namespace:WPFNetConnect.Helper" xmlns:prism="http://prismlibrary.com/" xmlns:validationRule="clr-namespace:WPFNetConnect.ValidationRules" Title="{Binding Title}" Width="1280" Height="800" prism:ViewModelLocator.AutoWireViewModel="True" WindowStartupLocation="CenterScreen"> <Window.Resources> <ResourceDictionary> <!-- 单独引入外部样式 --> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/Styles/LoginStyle.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="512" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Image Grid.Column="0" Style="{StaticResource LoginLeft}" /> <StackPanel Grid.Column="1" Style="{StaticResource LoginRight}"> <Label Style="{StaticResource LoginTitle}">欢迎回来</Label> <Label Style="{StaticResource LoginDesc}">登陆到您的账户</Label> <Label Style="{StaticResource LoginAccountTitle}">用户名</Label> <TextBox x:Name="LoginAccountTextBox" Style="{StaticResource LoginAccountTextBox}"> <Binding Path="Account"> <Binding.ValidationRules> <!-- 可以带参数,可以多条条件 --> <!-- validationRule:AccountLoginValidationRule Min="2" / --> <!-- validationRule:AccountLoginValidationRule Min="2" Max="10" / --> <validationRule:AccountLoginValidationRule /> </Binding.ValidationRules> </Binding> </TextBox> <Label Style="{StaticResource LoginPasswordTitle}">密码</Label> <PasswordBox x:Name="LoginPasswordBox" helper:PasswordBoxHelper.Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource LoginPasswordBox}" /> <Button Command="{Binding SubmitBtnCommand}" Content="登录" Style="{StaticResource LoginSubmitButton}" /> <Label Style="{StaticResource LoginErrorTip}">无法登录?联系管理员</Label> </StackPanel> <Label Grid.Column="1" Content="NetConnect v1.0.5" Style="{StaticResource LoginVersion}" /> </Grid> </Window>
- LoginViewModel.csusing log4net; using Prism.Commands; using Prism.Mvvm; using System; using System.CodeDom.Compiler; using System.Diagnostics; using System.Windows.Controls; using System.Windows.Input; namespace WPFNetConnect.ViewModels { public class LoginViewModel : BindableBase { private static readonly ILog _logger = LogManager.GetLogger(typeof(LoginViewModel)); private string _title = "Login"; public string Title { get { return _title; } set { SetProperty(ref _title, value); } } private string _account = ""; public string Account { get { return _account; } set { SetProperty(ref _account, value); // 当账号或密码改变时,重新计算提交按钮的可执行状态 SubmitBtnCommand?.RaiseCanExecuteChanged(); } } private string _password = ""; public string Password { get { return _password; } set { SetProperty(ref _password, value); // 当账号或密码改变时,重新计算提交按钮的可执行状态 SubmitBtnCommand?.RaiseCanExecuteChanged(); } } /// <summary> /// 点击登录按钮的命令 /// </summary> public DelegateCommand SubmitBtnCommand { get; set; } /// <summary> /// 是否可以提交 /// </summary> /// <returns></returns> public bool SubmitBtnCommandCanExecute() { return !string.IsNullOrEmpty(Account) && !string.IsNullOrEmpty(Password); } /// <summary> /// 点击登录按钮的执行方法 /// </summary> public void SubmitBtnCommandExecute() { _logger.Info("点击登录"); Debug.WriteLine(Account); Debug.WriteLine(Password); if ("admin".Equals(Account) && "123456".Equals(Password)) { System.Windows.MessageBox.Show("登录成功"); // Application.Current.MainWindow 就是当前的主窗口 var loginView = Application.Current.MainWindow; // 使用Prism框架的依赖注入容器来创建主窗口 var mainView = Container.Resolve<MainWindow>(); // 重新指定主窗口 Application.Current.MainWindow = mainView; mainView.Show(); loginView.Close(); } else { System.Windows.MessageBox.Show("登录失败"); } } public LoginViewModel() { SubmitBtnCommand = new DelegateCommand(SubmitBtnCommandExecute, SubmitBtnCommandCanExecute); } } }
    博  主 :夏秋初
地 址 :https://www.cnblogs.com/xiaqiuchu/p/18991478
 
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
    
地 址 :https://www.cnblogs.com/xiaqiuchu/p/18991478
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号