我有一个页面,在单击“保存”按钮之前,几个文本框不能为空。
<TextBox...
<TextBox.Text>
<Binding Path ="LastName" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:StringRequiredValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
我的规则有效。我的文本框周围有一个红色边框,直到我输入一个值。所以现在我想将此验证规则添加到我的其他文本框中。
现在,如何在页面没有错误之前禁用“保存”按钮?我不知道要检查什么是否有任何验证错误。
答案 0 :(得分:17)
以下是您需要的完整示例。
http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/
https://skydrive.live.com/?cid=2c6600f1c1d5e3be&id=2C6600F1C1D5E3BE%21203
答案 1 :(得分:15)
在视图的代码隐藏中,您可以像这样连接Validation.ErrorEvent;
this.AddHandler(Validation.ErrorEvent,new RoutedEventHandler(OnErrorEvent));
然后
private int errorCount;
private void OnErrorEvent(object sender, RoutedEventArgs e)
{
var validationEventArgs = e as ValidationErrorEventArgs;
if (validationEventArgs == null)
throw new Exception("Unexpected event args");
switch(validationEventArgs.Action)
{
case ValidationErrorEventAction.Added:
{
errorCount++; break;
}
case ValidationErrorEventAction.Removed:
{
errorCount--; break;
}
default:
{
throw new Exception("Unknown action");
}
}
Save.IsEnabled = errorCount == 0;
}
这假设您将收到删除通知(如果您删除有问题的元素,则不会发生这种情况。)
答案 2 :(得分:8)
您想使用附加属性Validation.HasError。
Josh Smith在Binding to (Validation.Errors)[0] without Creating Debug Spew上有一个有趣的读物。
答案 3 :(得分:3)
int count = 0;
private void LayoutRoot_BindingValidationError(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
{
button1.IsEnabled = false;
count++;
}
if (e.Action == ValidationErrorEventAction.Removed)
{
count--;
if (count == 0) button1.IsEnabled = true;
}
}
答案 4 :(得分:2)
这是一个帮助器方法,它跟踪依赖项对象(及其所有子代)的验证错误,并调用委托来通知有关更改。它还跟踪删除有验证错误的孩子。
public static void AddErrorHandler(DependencyObject element, Action<bool> setHasValidationErrors)
{
var errors = new List<Tuple<object, ValidationError>>();
RoutedEventHandler sourceUnloaded = null;
sourceUnloaded = (sender, args) =>
{
if (sender is FrameworkElement)
((FrameworkElement) sender).Unloaded -= sourceUnloaded;
else
((FrameworkContentElement) sender).Unloaded -= sourceUnloaded;
foreach (var error in errors.Where(err => err.Item1 == sender).ToArray())
errors.Remove(error);
setHasValidationErrors(errors.Any());
};
EventHandler<ValidationErrorEventArgs> errorHandler = (_, args) =>
{
if (args.Action == ValidationErrorEventAction.Added)
{
errors.Add(new Tuple<object, ValidationError>(args.OriginalSource, args.Error));
if (args.OriginalSource is FrameworkElement)
((FrameworkElement)args.OriginalSource).Unloaded += sourceUnloaded;
else if (args.OriginalSource is FrameworkContentElement)
((FrameworkContentElement)args.OriginalSource).Unloaded += sourceUnloaded;
}
else
{
var error = errors
.FirstOrDefault(err => err.Item1 == args.OriginalSource && err.Item2 == args.Error);
if (error != null)
errors.Remove(error);
}
setHasValidationErrors(errors.Any());
};
System.Windows.Controls.Validation.AddErrorHandler(element, errorHandler);
}
答案 5 :(得分:2)
就是这样 您需要从代码行为
中检查HasError控件属性并在保存按钮中单击
执行此代码 BindingExpression bexp = this.TextBox1.GetBindingExpression(TextBox.TextProperty);
bexp.UpdateSource(); // this to refresh the binding and see if any error exist
bool hasError = bexp.HasError; // this is boolean property indique if there is error
MessageBox.Show(hasError.ToString());
答案 6 :(得分:1)
只需从System.ComponentModel.IDataErrorInfo中获取ViewModel以进行验证 从INotifyPropertyChanged到通知按钮
make property:
public bool IsValid
{
get
{
if (this.FloorPlanName.IsEmpty())
return false;
return true;
}
}
在xaml中,将其连接到按钮
<Button Margin="4,0,0,0" Style="{StaticResource McVMStdButton_Ok}" Click="btnDialogOk_Click" IsEnabled="{Binding IsValid}"/>
在IDataErrorInfo覆盖中,通知btutton
public string this[string columnName]{
get
{
switch (columnName)
{
case "FloorPlanName":
if (this.FloorPlanName.IsEmpty())
{
OnPropertyChanged("IsValid");
return "Floor plan name cant be empty";
}
break;
}
}
}
答案 7 :(得分:1)
我已尝试过上述几种解决方案;然而,他们都没有为我工作。
我有一个简单的输入窗口,要求用户提供URI,如果TextBox
值不是有效Uri
,则应禁用Okay
按钮。
这对我有用:
CommandBindings.Add(new CommandBinding(AppCommands.Okay,
(sender, args) => DialogResult = true,
(sender, args) => args.CanExecute = !(bool) _uriTextBoxControl.GetValue(Validation.HasErrorProperty)));
答案 8 :(得分:0)
因为它仍然丢失,因此如果链接消失了,请改用开发人员的答案:
XAML:
<TextBox.Text Validation.Error="handleValidationError">
<Binding Path ="LastName"
UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="True">
<Binding.ValidationRules>
<local:StringRequiredValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<Button IsEnabled="{Binding HasNoValidationErrors}"/>
CodeBehind / C#:
private int _numberOfValidationErrors;
public bool HasNoValidationErrors => _numberOfValidationErrors = 0;
private void handleValidationError(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
_numberOfValidationErrors++;
else
_numberOfValidationErrors--;
}
答案 9 :(得分:0)
此网站包含您要查找的代码: https://www.wpfsharp.com/2012/02/03/how-to-disable-a-button-on-textbox-validationerrors-in-wpf/
对于后代,如果在输入字段上使用ValidationRule覆盖,则按钮代码应如下所示:
<Button Content="<NameThisButton>" Click="<MethodToCallOnClick>" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="false" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=<TextBoxName>, Path=(Validation.HasError)}" Value="false" />
<Condition Binding="{Binding ElementName=<TextBoxName>, Path=(Validation.HasError)}" Value="false" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="true" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>