【问题标题】:How to force a ItemsControl fo validate row changes?如何强制 ItemsControl 验证行更改?
【发布时间】:2012-06-18 00:01:22
【问题描述】:

我有一个名为PhoneModelModel 和一个名为PersonViewModelViewModel,它们都包含INotifyPropertyChangedIDataErrorInfo。在PersonViewModel 中,我有一个ObservableCollection<PhoneModel> Phones 属性,在我看来显示在ItemsControl 中。所以,我创建了一些Commands 来从Phones 添加和删除PhoneModel 项目。但是在添加、编辑和删除它们时,Validation 没有被触发。如何强制ItemsControl 验证其内容?有什么办法吗?

public class PhoneModel : INotifyPropertyChanged, IDataErrorInfo {
    // has some validation roles and IDataErrorInfo is implemented full
    public string Number { get; set; }
}

public class PersonViewModel : INotifyPropertyChanged, IDataErrorInfo { 
    public ObservableCollection<PhoneModel> Phones { get; set /* implements INotifyPropertyChanged */ ; }
}

在视野中:

<ItemsControl ItemsSource="{Binding Phones}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBox 
                    Text="{Binding Number,
                        UpdateSourceTrigger=PropertyChanged,
                        Mode=TwoWay,
                        ValidatesOnExceptions=True, 
                        NotifyOnValidationError=True,
                        ValidatesOnDataErrors=True}"
                    />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

你能帮帮我吗?提前致谢。

更新 1

我尝试@Michael Gs 的答案,但仍然无法正常工作。我的代码在这里:

1) 我添加了一个集合更改事件处理程序:

Phones.CollectionChanged += PhonesChanged;

2) 并在其中尝试:

void PhonesChanged(object sender, NotifyCollectionChangedEventArgs e) {
    if(e.Action != NotifyCollectionChangedAction.Remove)
        return;
    var model = e.OldItems[0] as PhoneModel;
    if(model != null) {
        model.Validate();
        OnPropertyChanged(() => Phones);
    }
}

3) 我也尝试监听每个电话项目的属性变化:

foreach(var phone in Phones)
    phone.PropertyChanged += new PropertyChangedEventHandler(phone_PropertyChanged);

和:

void phone_PropertyChanged(object sender, PropertyChangedEventArgs e) {
    var phone = sender as PhoneModel;
    if(phone == null)
        return;
    phone.Validate();
    OnPropertyChanged(() => Phones);
}

【问题讨论】:

  • @MichaelG 我该怎么做?我听不懂(我英语听不懂)
  • 什么验证没有运行? PhoneModel 验证,还是 PersonViewModel?您的 PhoneModel 验证应该正在运行,而您的 PhoneViewModel 验证不会。查看您的验证码也可能会有所帮助。
  • 实际上,当我设置断点时,似乎两个验证都运行了; PersonViewModelPhoneModelstring IDataErrorInfo.this[string columnName] getter 在它们的属性更改时调用;但是PersonViewModel的错误在视图中显示,而PhoneModel的错误在视图中没有任何影响
  • 关于接受评级,我明白了。行。谢谢
  • @Rachel 非常感谢你。我知道-刚刚-我的IDataErrorInfo impelementation 有一个错误(并且无法从资源文件中读取ErrorMessages)。所以代码没有错误!但没有任何错误信息可以显示。这是因为您的建议而发生的:"It might help to see your validation code as well"。再次感谢你

标签: wpf validation mvvm observablecollection idataerrorinfo


【解决方案1】:

在 Phones ObservableCollection 上收听 CollectionChanged 事件。

Phones.CollectionChanged += new NotifyCollectionChangedEventHandler(Phones_CollectionChanged);

void Phones_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
     //ValidatePhones();
     // OnPropertyChanged("Phones"); // Let IDataErrorInfo know
} 

此外,您可以在 PersonViewModel 中侦听每个“PhoneModel”的 PropertyChanged 事件,以便在 PhoneModel 对象上的属性发生更改时调用验证。

【讨论】:

  • 谢谢。我试试你的建议,但不起作用。我更新了 Q 并输入了我的尝试代码。可以看看吗?
  • 感谢您的建议。但实际上它对我没有帮助。错误是IDataErrorInfo 实现。我+1你的答案,但不能接受。再次感谢。问候
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 2013-08-22
相关资源
最近更新 更多