在按钮单击事件上实现IDataErrorInfo

时间:2017-11-16 09:12:07

标签: c# wpf data-binding ierrorhandler

我尝试使用绑定在按钮单击上实现文本框验证。基本上,当我点击提交时,我的文本框没有变成红色,并且给了我"必需"错误,是我向其添加文本的时候。

我在验证方面很陌生,并且在沮丧的情况下一直在观察这个问题近一个星期。我想我的回答可能与propertychangedevent有关吗?但我不确定并诉诸专业人士。

所有和任何帮助都必须得到赞赏。

这是我的Model类:

 public class sForms : INotifyPropertyChanged, IDataErrorInfo

{
    private string name;
    public string NAME { get { return name; } set { if (name != value) name = value.Trim(); OnPropertyChanged("NAME"); } }


    public string this[string columnName]
    {
        get
        {
            return ValidationError(columnName);
        }

    }

    public string Error { get { return null; } }


    private string ValidationError(string columnName)
    {
        string error = null;
        switch (columnName)
        {
            case "NAME":
                error = IsNameValid();
                break;
        }
        return 
            error;
    }

    static readonly string[] ValidatedProperties = { "NAME" };

    public bool IsValid
    {
        get
        {
            foreach (string property in ValidatedProperties)
            {
                if (ValidationError(property) != null)
                {
                    return
                        false;
                }
            }
            return
                true;
        }
    }

    public string IsNameValid()
    {
        if (string.IsNullOrWhiteSpace(NAME) || string.IsNullOrEmpty(NAME))
            return "Required";
        else
            return
                null;
    }


    #region Property Changed
    private void OnPropertyChanged(string propertyName)
    {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion
}

这是我的按钮+文本框的XAML;

        <TextBox Controls:TextBoxHelper.UseFloatingWatermark="True" 
                     Controls:TextBoxHelper.Watermark="Name *"                          
                     Grid.Column="1" Grid.Row="1"
                     Margin="0 0 2 0"         
                     Text="{Binding Path=NAME, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                     >
        <Button Content="Submit"                    
                Style="{DynamicResource SquareButtonStyle}"
                VerticalAlignment="Bottom" HorizontalAlignment="Right"
                Margin="0 0 10 0"    
                Click="Submit_Click"
                />

这是我背后的代码;

        public v_subsForm()
    {
        InitializeComponent();
        this.DataContext = subs;
    }

    sForms subs = new sForms();
    #region PropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion

    private void Submit_Click(object sender, RoutedEventArgs e)
    {
        if (subs.IsValid)
            MessageBox.Show("True");
        else
            MessageBox.Show("False");
    }

1 个答案:

答案 0 :(得分:0)

首先,假设您包含了所需的所有MahApps.Metro资源,您的代码将按预期工作。此外,您不需要在代码隐藏中实现INotifyPropertyChanged(我猜是您的MainWindow)。

  

我正在尝试使用绑定在按钮单击上实现文本框验证。

这不是IDataErrorInfo的工作原理。 IDataErrorInfo定义了一个API,绑定可以查询它绑定到的对象上的错误。因此,当您的NAME属性发生更改时,绑定将查询sForms对象上的索引器:subs["NAME"]。如果出现错误,则应用错误模板。这通常与提交按钮配对,其Command属性绑定到CanExecute检查错误的命令,如果有错误,则按钮被禁用(因此如果有错误则无法提交,按钮被禁用了。)

如果您想点击按钮进行验证,则无需实施IDataErrorInfoSystem.Windows.Controls.Validation类附加了可驱动错误呈现的属性:HasErrorErrorsErrorTemplate。但是,您不能将Validation.HasError设置为true(没有可访问的setter),就像您可以设置Validation.ErrorTemplate一样。要在代码隐藏中设置Validation.HasError,您可以使用Validation.MarkInvalid方法,但这不是通常的方法。这是一个快速示例,为此,您需要在Name上将TextBox属性设置为MyTextBox:

private void Submit_Click(object sender, RoutedEventArgs e)
{
    if (!string.IsNullOrEmpty(MyTextBox.Text)) return;

    BindingExpression bindingExpression = 
        BindingOperations.GetBindingExpression(MyTextBox, TextBox.TextProperty);

    BindingExpressionBase bindingExpressionBase =
        BindingOperations.GetBindingExpressionBase(MyTextBox, TextBox.TextProperty);

    ValidationError validationError =
        new ValidationError(new ExceptionValidationRule(), bindingExpression);

    validationError.ErrorContent = "My error message.";

    Validation.MarkInvalid(bindingExpressionBase, validationError);
}

因此,如果MyTextBox.Text为空,则视为无效。