Какой самый нормальный способ активировать/деактивировать кнопку в зависимости от того есть ли в UserControl'e ошибки валидации?
Есть некий юзер контрол, в каждом из полей происходит валидация.
<UserControl>
<TextBox>
<TextBox.Text>
<Binding ElementName="Ctrl1" Path="Days">
<Binding.ValidationRules>
<ExceptionValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox>
<TextBox.Text>
<Binding ElementName="Ctrl1" Path="TimeOfDay" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ExceptionValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</UserControl>
Теперь я хочу выключить кнопку если в контроле есть ошибки валидации:
<Button Content="Press" Click="Button_Click">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="false"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=CtrlTimeSpan, Path=(Validation.HasError)}" Value="False">
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=CtrlTimeSpan, Path=(Validation.HasError)}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Но оно не видит там ошибок, они видимо по дефолту не всплывают.
Влепил костылище, в CanExecute команды кнопки.
public static bool HasValidationErrors(this DependencyObject parent)
{
var stack = new Stack<DependencyObject>();
foreach (var child in LogicalTreeHelper.GetChildren(parent).OfType<DependencyObject>())
stack.Push(child);
while (stack.Any())
{
var child = stack.Pop();
if (Validation.GetErrors(child).Any())
return true;
foreach (var e in LogicalTreeHelper.GetChildren(child).OfType<DependencyObject>())
stack.Push(e);
}
return false;
}
Здравствуйте, UberPsychoSvin, Вы писали:
UPS>Влепил костылище, в CanExecute команды кнопки.
UPS>UPS>public static bool HasValidationErrors(this DependencyObject parent)
UPS>{
UPS>}
UPS>
Я делаю через BindingGroup:
<Window.BindingGroup>
<BindingGroup NotifyOnValidationError="True"/>
</Window.BindingGroup>
protected override void OnButtonClick(object selectedItem, CancelEventArgs args)
{
TaskDialogButtonData buttonData = selectedItem as TaskDialogButtonData;
if (buttonData != null)
{
if (buttonData.Button == TaskDialogButtons.OK)
{
BindingGroup bindingGroup = this.BindingGroup;
if (bindingGroup != null)
{
bool isValid = bindingGroup.ValidateWithoutUpdate();
foreach (BindingExpression expression in bindingGroup.BindingExpressions)
{
Binding binding = expression.ParentBinding;
if (binding.ValidationRules.Count > 0 || binding.ValidatesOnDataErrors)
{
expression.UpdateSource();
}
if (expression.HasError)
{
isValid = false;
}
}
args.Cancel = !isValid;
}
}
}
}
Только обратите внимание, что при использовании BindingGroup, необходимо для всех Binding в группе задать UpdateSourceTrigger. Иначе будет использоваться стандартный Explicit.