我仍然在WPF验证挣扎。
I'm still struggling with validation in WPF.
我有需要的文字出现在一个文本框,即它实施的强制性约束场自定义的验证规则。
I've got a custom validation rule which requires text to appear in a textbox i.e. it enforces a mandatory field constraint.
<TextBox local:Masking.Mask="^[a-zA-Z0-9]*$" x:Name="CameraIdCodeTextBox" Grid.Row="1" Grid.Column="1"> <Binding Path="CameraIdCode" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True" ValidatesOnExceptions="True"> <Binding.ValidationRules> <localValidation:RequiredFieldRule /> </Binding.ValidationRules> </Binding> </TextBox>问题是,当窗口第一次加载,还有在TextBox中没有文本(如你所期望的)。但是文本属性被绑定到的视图模型的属性,因此,验证规则被烧成,指示不存在与窗口的问题。 - 用户甚至有机会违反业务规则之前
The problem is, that when the Window first loads, there is no text in the TextBox (as you would expect). But the Text property is being bound to a property on the ViewModel, and as such, the validation Rule is firing, indicating that there is a problem with the Window - before the user has even had an opportunity to violate a business rule.
这是其之前已经解决的问题?我不能一直去体验这个第一。我敢肯定,这是对年轻球员的一个陷阱。
Is this a problem which has been solved before? I can't have been the 1st to experience this. I'm sure it is a trap for young players.
推荐答案这已经有一段时间,我应该已经更新了这个问题。我解决它使用一个类,我在WPF书发现由伊恩Griffths(O'Reilly的书):
It's been a while and I should have updated this question. I resolved it using a class which I found in a WPF book by Ian Griffths (an O'Reilly book):
public static class Validator { /// <summary> /// This method forces WPF to validate the child controls of the control passed in as a parameter. /// </summary> /// <param name="parent">Type: DependencyObject. The control which is the descendent root control to validate.</param> /// <returns>Type: bool. The validation result</returns> public static bool IsValid(DependencyObject parent) { // Validate all the bindings on the parent bool valid = true; LocalValueEnumerator localValues = parent.GetLocalValueEnumerator(); while (localValues.MoveNext()) { LocalValueEntry entry = localValues.Current; if (BindingOperations.IsDataBound(parent, entry.Property)) { Binding binding = BindingOperations.GetBinding(parent, entry.Property); foreach (ValidationRule rule in binding.ValidationRules) { ValidationResult result = rule.Validate(parent.GetValue(entry.Property), null); if (!result.IsValid) { BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property); Validation.MarkInvalid(expression, new ValidationError(rule, expression, result.ErrorContent, null)); valid = false; } } } } // Validate all the bindings on the children for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i) { DependencyObject child = VisualTreeHelper.GetChild(parent, i); if (!IsValid(child)) { valid = false; } } return valid; } }然后,在视图中,我有以下配置:
Then, on the view, I had the following configuration:
<TextBox local:Masking.Mask="^[0-9]*$" IsEnabled="{Binding Path=LocationNumberEnabled}" Grid.Row="1" Grid.Column="3"> <Binding Path="LocationNumber" Mode="TwoWay" UpdateSourceTrigger="LostFocus" NotifyOnValidationError="True" ValidatesOnExceptions="True"> <Binding.ValidationRules> <localValidation:PositiveNumberRule /> <localValidation:RequiredFieldRule /> </Binding.ValidationRules> </Binding> </TextBox>工作就像一个魅力!我只是叫IsValid的方法,每次我想手动验证例如时间一个按钮preSS。
Worked like a charm! I just called the IsValid method every time I wanted to manually validate e.g. on a button press.
更多推荐
验证绑定第一次加载
发布评论