在WPF中基于验证启用禁用按钮

本文关键字:启用 按钮 验证 WPF 于验证 | 更新日期: 2023-09-27 18:08:18

我有一个WPF表单,它有一个文本框和一个按钮。我正在验证文本框是否只有字符。验证工作很好,但我需要禁用按钮,如果有验证错误,使他们,如果没有验证错误。下面是我的代码:

<TextBox Name="tbProductName" Grid.Column="1" HorizontalAlignment="Left" Height="25" Margin="4,9,0,0" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Top" Width="213" 
                    Text="{Binding Path = ProductCode, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True,NotifyOnValidationError=True}">               
            <Validation.ErrorTemplate>
                <ControlTemplate>
                    <StackPanel>
                        <AdornedElementPlaceholder x:Name="textBox"/>
                        <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red"/>
                    </StackPanel>
                </ControlTemplate>
            </Validation.ErrorTemplate>
        </TextBox>
        <Button Name ="btnDownload" Content="Download" Grid.Column="2" HorizontalAlignment="Left" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="87" Height="24" Click="btnDownload_Click"/>

public class ViewModel: System.ComponentModel.INotifyDataErrorInfo 
   {
       private readonly Dictionary<string, ICollection<string>> _validationErrors = new Dictionary<string, ICollection<string>>();
       private readonly Model _productCode = new Model();
       public string ProductCode
       {
           get { return _productCode.ProductCode; }
           set
           {
               _productCode.ProductCode = value;
               ValidateModelProperty(value, "ProductCode");
           }
       }
       protected void ValidateModelProperty(object value, string propertyName)
       {
           if (_validationErrors.ContainsKey(propertyName))
               _validationErrors.Remove(propertyName);
           PropertyInfo propertyInfo = _productCode.GetType().GetProperty(propertyName);
           IList<string> validationErrors =
                 (from validationAttribute in propertyInfo.GetCustomAttributes(true).OfType<ValidationAttribute>()
                  where !validationAttribute.IsValid(value)
                  select validationAttribute.FormatErrorMessage(string.Empty))
                  .ToList();
           _validationErrors.Add(propertyName, validationErrors);
           RaiseErrorsChanged(propertyName);
       }
         /* Raise the ErrorsChanged for all properties explicitly */
       protected void ValidateModel()
       {
           _validationErrors.Clear();
           ICollection<ValidationResult> validationResults = new List<ValidationResult>();
           ValidationContext validationContext = new ValidationContext(_productCode, null, null);
           if (!Validator.TryValidateObject(_productCode, validationContext, validationResults, true))
           {
               foreach (ValidationResult validationResult in validationResults)
               {
                   string property = validationResult.MemberNames.ElementAt(0);
                   if (_validationErrors.ContainsKey(property))
                   {
                       _validationErrors[property].Add(validationResult.ErrorMessage);
                   }
                   else
                   {
                       _validationErrors.Add(property, new List<string> { validationResult.ErrorMessage });
                   }
               }
           }
           /* Raise the ErrorsChanged for all properties explicitly */
           RaiseErrorsChanged("ProductCode");
       }
       #region INotifyDataErrorInfo members
       public event EventHandler<System.ComponentModel.DataErrorsChangedEventArgs> ErrorsChanged;
       private void RaiseErrorsChanged(string propertyName)
       {
           if (ErrorsChanged != null)
               ErrorsChanged(this, new System.ComponentModel.DataErrorsChangedEventArgs(propertyName));
       }
       public System.Collections.IEnumerable GetErrors(string propertyName)
       {
           if (string.IsNullOrEmpty(propertyName)
               || !_validationErrors.ContainsKey(propertyName))
               return null;
           return _validationErrors[propertyName];
       }
       public bool HasErrors
       {
           get { return _validationErrors.Count > 0; }
       }
       #endregion
    }  
public class Model
    {
        [Required(ErrorMessage = "You must enter a product code to download.")]
        [RegularExpression(@"^[a-zA-Z]+$", ErrorMessage = "The Product Code must only contain letters (a-z, A-Z).")]
        public string ProductCode { get; set; }
    }

如何将按钮的isEnabled属性设置为validate . haserrors ?

在WPF中基于验证启用禁用按钮

理想情况下,您的按钮将绑定它的"Command"属性到公共ICommand视图模型属性。

CanExecute方法将被求值,返回真或假。该按钮将相应地启用/禁用。

您可以在这里阅读更多关于iccommand的信息,以及接口的实现。

下面是所需的更改,假设您使用上述文章中描述的RelayCommand(参见图3)实现。

注册命令

private readonly ICommand _downloadCommand = new RelayCommand(OnDownload, CanDownload);

用于绑定:

public ICommand DownloadCommand { get { return _downloadCommand; } }

命令执行时调用的方法:

private void OnDownload(object parameter) { ... Do your download code here ... }
private bool CanDownload(object parameter) { return HasErrors == false; }

更新你的XAML绑定:

<Button Content="Download" Grid.Column="2" HorizontalAlignment="Left" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="87" Height="24" Command="{Binding DownloadCommand}" />

我建议对Binding使用与其他代码相同的技术!!

在你的xaml

<Button Name ="btnDownload"  IsEnabled="{Binding Path= BtnIsEnabled} click="btnDownload_Click"/>

在你的代码

    public bool BtnIsEnabled
    {
        get { return this._BtnIsEnabled; }
        set
        {
            this._BtnIsEnabled = value;
            base.OnPropertyChanged("BtnIsEnabled");
        }
    }
    private bool _BtnIsEnabled;

然后在你想要禁用Button的地方输入

BtnIsEnabled = Validation.HasErrors ? false : true ;

显然这是一个伪涂鸦。除非你要找什么特别的东西而我又找不到。似乎你已经在你的代码中使用绑定,我猜你知道如何。