我的 WPF 应用程序中有以下场景:
- 用户在文本框中输入一个值。
- 我启动一个后台线程来验证该值(通过 Web 服务调用)。
(98% 的时间输入有效。) - 用户离开文本框并继续处理下一个文本框。
- 后台线程返回,结果表明输入无效。
它通过触发事件让 View 模型知道这一点。 (我正在使用 Prism 事件和模块。)
我需要一种方法让该事件让 TextBox 知道给定的输入存在验证错误。 (请记住,焦点不再位于该控件中。)
我可以想出各种方法来“滚动我自己的验证”并完成这项工作。但我想在 WPF 的现有验证框架内工作。
注意:我不确定它是否相关,但我需要维护一个“NeededValidations”列表,在启用“保存”按钮之前,所有这些都必须通过。
最佳答案
您可以尝试以下几种使用 IDataErrorInfo 的方法。它们都依赖于引发 INotifyPropertyChanged 通知将导致重新评估绑定(bind)验证这一事实。
有两个文本框。一种使用异步绑定(bind)并假定 Web 服务调用是同步的。第二种使用同步绑定(bind)并假定 Web 服务调用是异步的。
XAML
<Window.DataContext>
<WpfValidationUpdate:ViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Margin="5" Grid.Row="0" Text="{Binding Text1, IsAsync=True, ValidatesOnDataErrors=True}"/>
<TextBox Margin="5" Grid.Row="1" Text="{Binding Text2, ValidatesOnDataErrors=True}"/>
</Grid>
查看模型
public class ViewModel : IDataErrorInfo, INotifyPropertyChanged
{
private string _text1;
private string _text2;
private bool _text1ValidationError;
private bool _text2ValidationError;
#region Implementation of IDataErrorInfo
public string this[string columnName]
{
get
{
if(columnName == "Text1" && _text1ValidationError)
{
return "error";
}
if(columnName == "Text2" && _text2ValidationError)
{
return "error";
}
return string.Empty;
}
}
public string Error
{
get
{
return string.Empty;
}
}
public string Text1
{
get { return _text1; }
set
{
_text1 = value;
OnPropertyChanged("Text1");
// Simulate web service synchronously taking a long time
// Relies on async binding
Thread.Sleep(2000);
_text1ValidationError = true;
OnPropertyChanged("Text1");
}
}
public string Text2
{
get { return _text2; }
set
{
_text2 = value;
OnPropertyChanged("Text2");
// Simulate web service asynchronously taking a long time
// Doesn't rely on async binding
Task.Factory.StartNew(ValidateText2);
}
}
private void ValidateText2()
{
Thread.Sleep(2000);
_text2ValidationError = true;
OnPropertyChanged("Text2");
}
#endregion
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if(handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
关于wpf - 使用 WPF 延迟输入验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10401414/