为什么 IDataErrorInfo 会多次触发?

发布于 2024-12-06 08:21:00 字数 2690 浏览 0 评论 0原文

我遇到的问题是 IDataErrorInfo 多次被解雇。

Transaction Class

public class Transaction : INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo
{

private Double? _transAmount;

[Column(DbType = "decimal(19,4)")]
public Double? TransAmount
{
    get { return _transAmount; }
    set
    {
        if (_transAmount != value)
        {
            NotifyPropertyChanging("TransAmount");
            _transAmount = value;
            NotifyPropertyChanged("TransAmount");
        }
    }
}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

// Used to notify that a property changed
private void NotifyPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

#endregion

#region INotifyPropertyChanging Members

public event PropertyChangingEventHandler PropertyChanging;

// Used to notify that a property is about to change
private void NotifyPropertyChanging(string propertyName)
{
    if (PropertyChanging != null)
    {
        PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
    }
}

#endregion

#region Data Validation

public string Error { get { return null; } }

public string this[string property]
{
    get
    {
        switch (property)
        {
            case "TransAmount":
                if (TransAmount != null)
                {
                    double value;
                    bool valid = double.TryParse(TransAmount.ToString(), out value);

                    if (!valid) { return TransAmount.ToString() + " is not a valid number"; }
                    else if (value <= 0) { return "Dollar amount must be greater than $0.00"; }
                }
                return null;
            default:
                return null;
        }
    }
}

#endregion

} 

和 xaml

<toolkit:PhoneTextBox Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch"
                        x:Name="txtAmount" Width="Auto" 
                        Text="{Binding TransAmount, Mode=TwoWay, NotifyOnValidationError=True, StringFormat=\{0:c\}, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"
                        BindingValidationError="txtAmount_BindingValidationError" InputScope="CurrencyAmount"
                        GotFocus="txtAmount_GotFocus"
                        LostFocus="txtAmount_LostFocus">
</toolkit:PhoneTextBox>

我不确定该模式,但验证方法被命中 2-3 次?为什么?

编辑1 TransAmount 值正在 txtAmount_LostFocus 事件中设置。

编辑2 添加了 WP7 标签

I am having an issue where IDataErrorInfo is getting fired multiple times.

Transaction Class

public class Transaction : INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo
{

private Double? _transAmount;

[Column(DbType = "decimal(19,4)")]
public Double? TransAmount
{
    get { return _transAmount; }
    set
    {
        if (_transAmount != value)
        {
            NotifyPropertyChanging("TransAmount");
            _transAmount = value;
            NotifyPropertyChanged("TransAmount");
        }
    }
}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

// Used to notify that a property changed
private void NotifyPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

#endregion

#region INotifyPropertyChanging Members

public event PropertyChangingEventHandler PropertyChanging;

// Used to notify that a property is about to change
private void NotifyPropertyChanging(string propertyName)
{
    if (PropertyChanging != null)
    {
        PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
    }
}

#endregion

#region Data Validation

public string Error { get { return null; } }

public string this[string property]
{
    get
    {
        switch (property)
        {
            case "TransAmount":
                if (TransAmount != null)
                {
                    double value;
                    bool valid = double.TryParse(TransAmount.ToString(), out value);

                    if (!valid) { return TransAmount.ToString() + " is not a valid number"; }
                    else if (value <= 0) { return "Dollar amount must be greater than $0.00"; }
                }
                return null;
            default:
                return null;
        }
    }
}

#endregion

} 

and the xaml

<toolkit:PhoneTextBox Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch"
                        x:Name="txtAmount" Width="Auto" 
                        Text="{Binding TransAmount, Mode=TwoWay, NotifyOnValidationError=True, StringFormat=\{0:c\}, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"
                        BindingValidationError="txtAmount_BindingValidationError" InputScope="CurrencyAmount"
                        GotFocus="txtAmount_GotFocus"
                        LostFocus="txtAmount_LostFocus">
</toolkit:PhoneTextBox>

I'm not sure of the pattern, but validation method is getting hit 2-3 times? Why?

Edit 1
The value TransAmount is being set in the txtAmount_LostFocus event.

Edit 2
Added WP7 tag

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

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

发布评论

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

评论(1

冷︶言冷语的世界 2024-12-13 08:21:00

诀窍如下。

使用 DataErrorValidationRule 而不是 ValidatesOnDataErrors=True。

<TextBox>
    <TextBox.Text>
        <Binding Path="..." UpdateSourceTrigger="LostFocus" NotifyOnValidationError="True">
                <Binding.ValidationRules>
                    <DataErrorValidationRule ValidatesOnTargetUpdated="False"/>
                </Binding.ValidationRules>
            </Binding>
     </TextBox.Text>
</TextBox>

请参阅本文https://social.msdn.microsoft.com/forums/vstudio/en-US/099164f8-72aa-4c59-a7b6-7ccbd56702ce/idataerrorinfo-validation-known-twice

The trick is the following.

Use DataErrorValidationRule instead of ValidatesOnDataErrors=True.

<TextBox>
    <TextBox.Text>
        <Binding Path="..." UpdateSourceTrigger="LostFocus" NotifyOnValidationError="True">
                <Binding.ValidationRules>
                    <DataErrorValidationRule ValidatesOnTargetUpdated="False"/>
                </Binding.ValidationRules>
            </Binding>
     </TextBox.Text>
</TextBox>

Refer to this article https://social.msdn.microsoft.com/forums/vstudio/en-US/099164f8-72aa-4c59-a7b6-7ccbd56702ce/idataerrorinfo-validation-called-twice

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