【问题标题】:IDataErrorInfo validate before binding occurs在绑定发生之前验证 IDataErrorInfo
【发布时间】:2014-01-27 20:16:23
【问题描述】:

我想在 WPF 中进行一些简单的文本框验证,但我刚刚意识到 IDataErrorInfo 依赖于引发 PropertyChanged 事件来触发验证,这意味着在验证发生之前将无效值应用于我的绑定对象。有没有办法改变这一点,以便首先进行验证(并防止绑定无效数据),或者是否有另一种解决方案可以这样工作?

精简后的代码如下所示:

<TextBox>
    <TextBox.Text>
        <Binding Path="MyProperty" ValidatesOnDataErrors="True" />
    </TextBox.Text>
</TextBox>

public class MyViewModel : IDataErrorInfo
{
    public string MyProperty
    {
        get { return _myProperty; }
        set
        {
            if (_myProperty != value)
            {
                _myProperty = value;
                NotifyPropertyChanged(() => MyProperty);
                SaveSettings();
            }
        }
    }

    public string Error
    {
        get { return string.Empty; }
    }

    public string this[string columnName]
    {
        get
        {
            if (columnName == "MyProperty")
                return "ERROR";
            return string.Empty;
        }
    }
}

【问题讨论】:

标签: c# wpf


【解决方案1】:

使用更好的接口和验证方法(如果使用 .net 4.5)是INotifyDataErrorInfo。它的主要优点是允许您控制验证发生的时间和方式。一个很好的概述:

http://anthymecaillard.wordpress.com/2012/03/26/wpf-4-5-validation-asynchrone/

【讨论】:

    【解决方案2】:

    我认为您不需要在每次属性更改时调用 SaveSettings() 方法。我认为应该在用户单击“保存”按钮时调用它,而不是在属性更改时调用。但是,如果您仍想保存对属性更改的更改,则只有在没有可用的验证错误时才应该这样做。例如:

    public class MyViewModel : IDataErrorInfo
    {
        public string MyProperty
        {
            get { return _myProperty; }
            set
            {
                if (_myProperty != value)
                {
                    _myProperty = value;
                    NotifyPropertyChanged(() => MyProperty);
                    if (string.IsNullOrEmpty(this["MyProperty"]))
                    {
                        SaveSettings();
                    }
                }
            }
        }
    
        public string Error
        {
            get { return string.Empty; }
        }
    
        public string this[string columnName]
        {
            get
            {
                if (columnName == "MyProperty")
                    return "ERROR";
                return string.Empty;
            }
        }
    }
    

    【讨论】:

    • 这不会导致每次更改都执行两次验证吗?
    • 可能是这样,在这种情况下,您可以设置一些存在错误的标志,或者添加另一个属性“IsValid”,例如本例中的stackoverflow.com/questions/13603243/…
    • 但我建议从属性中使用 SaveSettings() 方法,并将其绑定到某个按钮或其他控制操作。属性不应该有动作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 2012-06-07
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多