IDataErrorInfo:不验证输入

发布于 2024-07-15 01:25:57 字数 2038 浏览 8 评论 0原文

我有一个包含文本框的用户控件。 我有一个名为 Person 的类,它实现了 IDataErrorInfo 接口:

class Person : IDataErrorInfo
{
private bool hasErrors = false;
#region IDataErrorInfo Members

        public string Error
        {            
            get 
            {
                string error = null;
                if (hasErrors)
                {
                    error = "xxThe form contains one or more validation errors";
                }
                return error;
            }
        }

        public string this[string columnName]
        {
            get 
            {
                return DoValidation(columnName);
            }
        }
        #endregion
}

现在,用户控件公开了一个名为 SetSource 的方法,代码通过该方法设置绑定:

public partial class TxtUserControl : UserControl 
    {          
        private Binding _binding;

        public void SetSource(string path,Object source)
        {
            _binding = new Binding(path);
            _binding.Source = source;
            ValidationRule rule;
            rule = new DataErrorValidationRule();
            rule.ValidatesOnTargetUpdated = true;            
            _binding.ValidationRules.Add(rule);
            _binding.ValidatesOnDataErrors = true;
            _binding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
            _binding.NotifyOnValidationError = true;            
            _binding.ValidatesOnExceptions = true;
            txtNumeric.SetBinding(TextBox.TextProperty, _binding);                
        }
...
}

包含用户控件的 WPF 窗口具有以下代码:

public SampleWindow()
    {
        person= new Person();
        person.Age = new Age();
        person.Age.Value = 28;

        numericAdmins.SetSource("Age.Value", person);
    }
    private void btnOk_Click(object sender, RoutedEventArgs e)
    {         

        if(!String.IsNullOrEmpty(person.Error))
        {
            MessageBox.Show("Error: "+person.Error);
        }
    }

给定此代码,绑定工作正常,但验证永远不会被触发。 这段代码有什么问题吗?

I have a user control which contains a textbox. I have a class called Person which implements IDataErrorInfo interface:

class Person : IDataErrorInfo
{
private bool hasErrors = false;
#region IDataErrorInfo Members

        public string Error
        {            
            get 
            {
                string error = null;
                if (hasErrors)
                {
                    error = "xxThe form contains one or more validation errors";
                }
                return error;
            }
        }

        public string this[string columnName]
        {
            get 
            {
                return DoValidation(columnName);
            }
        }
        #endregion
}

Now the usercontrol exposes a method called SetSource through which the code sets the binding:

public partial class TxtUserControl : UserControl 
    {          
        private Binding _binding;

        public void SetSource(string path,Object source)
        {
            _binding = new Binding(path);
            _binding.Source = source;
            ValidationRule rule;
            rule = new DataErrorValidationRule();
            rule.ValidatesOnTargetUpdated = true;            
            _binding.ValidationRules.Add(rule);
            _binding.ValidatesOnDataErrors = true;
            _binding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
            _binding.NotifyOnValidationError = true;            
            _binding.ValidatesOnExceptions = true;
            txtNumeric.SetBinding(TextBox.TextProperty, _binding);                
        }
...
}

The WPF window that includes the user control has the following code:

public SampleWindow()
    {
        person= new Person();
        person.Age = new Age();
        person.Age.Value = 28;

        numericAdmins.SetSource("Age.Value", person);
    }
    private void btnOk_Click(object sender, RoutedEventArgs e)
    {         

        if(!String.IsNullOrEmpty(person.Error))
        {
            MessageBox.Show("Error: "+person.Error);
        }
    }

Given this code, the binding is working fine, but the validation never gets triggered. Whats wrong with this code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寄意 2024-07-22 01:25:57

您的 Age 类需要实现 IDataErrorInfo。 您的 Person 类不会被要求验证 Age 的属性。

如果这不是一个选择,我为 WPF 编写了一个验证系统,该系统的可扩展性足以支持这一点。 URL 位于:

ZIP 是一个描述它的Word 文档。

编辑:这是年龄可以实现 IDataErrorInfo 而不会太聪明的一种方法:

class Constraint 
{
    public string Message { get; set; }
    public Func<bool> Validate;
    public string Name { get; set; }
}

class Age : IDataErrorInfo
{
    private readonly List<Constraint> _constraints = new List<Constraint>();

    public string this[string columnName]
    {
        get 
        {
            var constraint = _constrains.Where(c => c.Name == columnName).FirstOrDefault();
            if (constraint != null)
            {
                if (!constraint.Validate())
                {
                    return constraint.Message;
                }
            }
            return string.Empty;
        }
    }
}

class Person
{
    private Age _age;

    public Person() 
    {
        _age = new Age(
            new Constraint("Value", "Value must be greater than 28", () => Age > 28);
    }
}

另请参阅此链接:

http ://www.codeproject.com/KB/cs/DelegateBusinessObjects.aspx

Your Age class will need to implement IDataErrorInfo. Your Person class won't be asked to validate the Age's properties.

If that is not an option, I wrote a validation system for WPF that is extensible enough to support this. The URL is here:

In the ZIP is a word document describing it.

Edit: here's one way age could implement IDataErrorInfo without being too smart:

class Constraint 
{
    public string Message { get; set; }
    public Func<bool> Validate;
    public string Name { get; set; }
}

class Age : IDataErrorInfo
{
    private readonly List<Constraint> _constraints = new List<Constraint>();

    public string this[string columnName]
    {
        get 
        {
            var constraint = _constrains.Where(c => c.Name == columnName).FirstOrDefault();
            if (constraint != null)
            {
                if (!constraint.Validate())
                {
                    return constraint.Message;
                }
            }
            return string.Empty;
        }
    }
}

class Person
{
    private Age _age;

    public Person() 
    {
        _age = new Age(
            new Constraint("Value", "Value must be greater than 28", () => Age > 28);
    }
}

Also see this link:

http://www.codeproject.com/KB/cs/DelegateBusinessObjects.aspx

蔚蓝源自深海 2024-07-22 01:25:57

另一种选择是在 Age 类上实现 IDataErrorInfo 并在其上创建一个事件,例如应由 Person 类捕获的 OnValidationRequested 事件。 这样您就可以根据 Person 类的其他属性来验证 Age 字段。

Another option could be to implement IDataErrorInfo on the Age class and create an event on it like OnValidationRequested that should be captured by the Person class. This way you could validate the Age field based on other properties of the Person class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文