【问题标题】:Stack OverFlow with Custom validatorStack OverFlow 与自定义验证器
【发布时间】:2016-12-22 06:29:34
【问题描述】:

我已经实现了如下的自定义验证器...

 public class RquiredFiledValidation:ValidationRule
{
    public string ErrorMessage { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        if (string.IsNullOrWhiteSpace(value.ToString()))
            return new ValidationResult(false, ErrorMessage);
        else
            return new ValidationResult(true, null);
    }
}

并附上如下文本框...

 <TextBox x:Name="txtLoging" Grid.Column="1" HorizontalAlignment="Stretch" Validation.ErrorTemplate="{x:Null}" VerticalAlignment="Center"  Margin="0,40,30,0">
        <Binding Path="Text" ElementName="txtLoging" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
            <Binding.ValidationRules>
                <Validate:RquiredFiledValidation  ErrorMessage="Please Provide Login Name"></Validate:RquiredFiledValidation>
            </Binding.ValidationRules>
        </Binding>
    </TextBox>

我的问题是……

1) 当我直接点击登录按钮时,验证不会被触发

2) 当我在文本框中输入一个字符时,验证被触发但产生堆栈溢出错误。

【问题讨论】:

  • 当我改变 UpdateSourceTrigger="LostFocus" 它停止工作。
  • 你是如何显示错误的?你有任何样式或validation.ErrorTemplate 吗?提供堆栈溢出错误详细信息。
  • 是的,我在资源中为错误模板定义了控制模板。我已经解决了第二个问题。但第一个问题仍然存在。我遇到了另一个问题,即错误消息与其他控件重叠。
  • 第一个问题的任何帮助..当我直接点击登录按钮时,验证不会被触发
  • 你在使用 MVVM 吗?

标签: c# wpf customvalidator


【解决方案1】:

我已经从下面的代码中解决了第一个问题 txtLoging.GetBindingExpression(TextBox.TextProperty).UpdateS‌​ource(); txtPassword.GetBindingExpression(Infrastructure.AttachedProp‌​erty.PasswordAssiste‌​nt.PasswordValue).Up‌​dateSource();但是如何在 MVVM 中解决同样的问题

如果您关心 MVVM 模式,则不应使用验证规则来验证您的数据。验证规则属于视图,在 MVVM 应用程序中,验证逻辑应在视图模型或模型类中实现。

你应该做的是实现INotifyDataErrorInfo接口:https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo%28v=vs.110%29.aspx

这里有一个例子:

public class ViewModel : INotifyDataErrorInfo
{
    private string _username;
    public string Username
    {
        get { return _username; }
        set
        {
            _username = value;
            ValidateUsername();
        }
    }

    private void ValidateUsername()
    {
        if (_username == "valid")
        {
            if (_validationErrors.ContainsKey("Username"))
                _validationErrors.Remove(nameof(Username));
        }
        else if (!_validationErrors.ContainsKey("Username"))
        {
            _validationErrors.Add("Username", new List<string> { "Invalid username" });
        }

        RaiseErrorsChanged("Username");
    }


    private readonly Dictionary<string, ICollection<string>>
        _validationErrors = new Dictionary<string, ICollection<string>>();

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
    private void RaiseErrorsChanged(string propertyName)
    {
        if (ErrorsChanged != null)
            ErrorsChanged(this, new 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; }
    }
}

<TextBox Text="{Binding Username, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True}" />

请参阅以下博客文章,了解有关 WPF 中数据验证工作原理的详细信息以及有关如何实现它的一些综合示例。

WPF 中的数据验证: https://blog.magnusmontin.net/2013/08/26/data-validation-in-wpf/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    相关资源
    最近更新 更多