【问题标题】:Run validation when a user input something in a text field当用户在文本字段中输入内容时运行验证
【发布时间】:2014-08-21 12:16:26
【问题描述】:

如果我希望在用户在文本字段中输入内容而不是在弹出窗口时运行验证,我需要做什么。这是示例图片:

在我执行此窗口时的示例图像中,它会自动验证。我希望它在我输入内容时检查验证。

这是我在验证中的代码 sn-p:

public string Error
    {
        get { return null; }
    }

    public string this[string propertyName]
    {
        get
        {
            string error = string.Empty;
                switch (propertyName)
                {
                    case "Name":
                        if (string.IsNullOrEmpty(Name))
                            error = "Name is required!";
                        break;
                    case "Url":
                        if (string.IsNullOrEmpty(Url))
                            error = "Url is required!";
                        else if (!Regex.IsMatch(Url, @"(?:https?:\/\/)?(?:[\w]+\.)([a-zA-Z\.]{2,6})([\/\w\.-]*)*\/?"))
                            error = "Url is invalid";
                        break;
                    case "Price":
                        if (Price < 0)
                            error = "Price cannot be negative!";
                        break;
                    default:
                        break;
                }

            return error;
        }
    }

这是我 UI 中的代码 sn-p:

 <!--Product Name-->
    <Label Content="Name:" />
    <TextBox x:Name="txtName" 
             Grid.Column="2"
             Validation.Error="ValidationError"
             Text="{Binding Name, 
                    Mode=TwoWay, 
                    ValidatesOnDataErrors=True,
                    NotifyOnValidationError=True,
                    UpdateSourceTrigger=PropertyChanged}" />
    <!--Product Url-->
    <Label Grid.Row="2" Content="Url:" />
    <TextBox x:Name="txtUrl" 
             Grid.Row="2" 
             Grid.Column="2"
             Validation.Error="ValidationError"
             Text="{Binding Url, 
                    Mode=TwoWay, 
                    ValidatesOnDataErrors=True,
                    NotifyOnValidationError=True,
                    UpdateSourceTrigger=PropertyChanged}"/>

【问题讨论】:

    标签: c# wpf validation telerik radwindow


    【解决方案1】:

    如果“当我输入内容时”是指“每次我按下一个键”,则将 TextBox 上的 Binding UpdateSourceTrigger 值更改为 PropertyChanged。这意味着每当TextBox的值发生变化时,它会自动更新绑定的对象并触发IDataErrorInfo接口调用来更新TextBox的状态。

    更新:

    您需要实现INotifyPropertyChanged 接口才能让IDataErrorInfo 正常工作。

    public class MyObject : INotifyPropertyChanged, IDataErrorInfo
    {
    
     public event PropertyChangedEventHandler PropertyChanged;
    
     private string _myValue;
     public string MyValue
     {
       get { return _myValue; }
       set 
       {
         _myValue = value;
         OnPropertyChanged("MyValue");
       }
     }
    
     private void OnPropertyChanged(string propertyName)
     {
         var handler = PropertyChanged;
         if (handler != null)
         PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
     }
    
     public string Error
        {
            get { return null; }
        }
    
        public string this[string columnName]
        {
            get
            {
                string returnValue = null;
                switch (columnName)
                {
                    case "MyValue":
                       if MyValue != "expected"
                          returnValue = "MyValue is not expected";
                }
                return returnValue;
             }
        }
    
    }
    

    注意: IDataErrorInfo 仅在向 UI 更新通知后检索到 MyValue 时调用(因此在索引器中实现 get 而不是 set

    【讨论】:

    • 能否将 Url 属性的声明添加到代码 sn-ps 中?
    • 它是public string url {get; set;}
    • 这是你的问题。您需要在 ViewModel 对象中实现INotifyPropertyChanged。当您调用set 时,您需要提高PropertyChangedEvent 以通知整个Binding 子系统发生了一些事情。
    • 你能举个例子吗?
    • 更新了示例和解释。
    【解决方案2】:

    我建议您使用IDataErrorInfo Interface 来验证您的数据对象,主要有两个原因...首先,它比使用ValidationRules 更通用,其次因为拥有您的数据验证代码更有意义在您的模型中使用您的数据属性。

    接着,Binding 类中有一个名为 UpdateSourceTrigger 的属性,获取或设置一个确定绑定源更新时间的值。请参阅 MSDN 上的 Binding.UpdateSourceTrigger Property 页面有关完整信息,但基本上,此属性会影响属性更改何时传递到 Binding 源。

    如果您将此属性设置为UpdateSourceTrigger.LostFocus,那么它只会在当前控件失去焦点时更新Binding 值,例如。当用户选项卡到另一个控件时。还有另一个值 UpdateSourceTrigger.Explicit,您可能更喜欢它,因为这有效地推迟了属性更改,直到您手动调用 BindingExpression.UpdateSource Method

    现在我可能在这里弄错了,但据我所知,如果没有属性更改,则没有验证检查(使用IDataErrorInfo 接口时)。

    最后,如果这些都不起作用,请查看我对How to prevent validation until the user enters data into a field? 问题的回答。

    【讨论】:

    • 我正在使用 IDataErrorInfo,实际上我正在使用我在这里下载的库:link
    • 我检查了您对您提供的链接的回答,将详细解释INotifyPropertyChanged.PropertyChanged 的使用。我还是 C# 编程的新手,仍然缺乏知识。谢谢!
    • INotifyPropertyChanged Interface 使用该事件来传递刚刚更改的属性的名称。它负责在 UI 和数据源之间启用双向数据绑定。
    • 正如我在回答中所说,将Binding.UpdateSourceTrigger 设置为除PropertyChanged 之外的任何内容,这将立即更新Bindings ......没有属性更改应该意味着不应该进行验证。只需跳进去试一试...如果您不确定,请尝试一个新的小项目。
    • 有一个IsValidatable条件封装了验证数据对象的代码,所以如果设置为false,那么数据对象就不会被验证...关于IDataErrorInfo 接口比INotifyPropertyChanged 接口。
    猜你喜欢
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多