wpf - 使用 WPF 延迟输入验证

标签 wpf validation xaml .net-4.0

我的 WPF 应用程序中有以下场景:

  1. 用户在文本框中输入一个值。
  2. 我启动一个后台线程来验证该值(通过 Web 服务调用)。
    (98% 的时间输入有效。)
  3. 用户离开文本框并继续处理下一个文本框。
  4. 后台线程返回,结果表明输入无效。
    它通过触发事件让 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/

相关文章:

c# - 使用 MVVM 绑定(bind)菜单抛出异常

c# - 如何在 App.Config 中设置相对路径?

.net - WindowsFormsHost 是否适合(.net WPF 托管 WinForms)?

c# - 如何在 VS WPF 设计面板中显示集合数据?

wpf - ValidatesOnExceptions 的工作原理

javascript - 让 jQuery 动态字段独一无二

c# - xamarin 形成清除选择器选择

c# - viewModel之间使用MVVM方式的接口(interface)进行通信

PHP 输入验证和处理 MySQL 错误 : What's The Safest Route?

c# - 为什么我的命名 WPF 形状无法从代码隐藏中访问?