Disabling button on Validation error
Solution 1
You can use MultiDataTrigger
property in Style.Triggers
of Button
. Let's assume that we have a TextBox
named "txtName". We have to disable button "btnSave" on the validation error of TextBox
.
Here is what you can do:
<Button Content="Save"
Grid.Column="1"
Grid.Row="3"
HorizontalAlignment="Right"
Height="23"
Name="btnSave"
Width="75"
IsDefault="True"
Command="{Binding SaveProtocolCommand}"
Margin="3">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=txtName}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Hope this will help you.
Solution 2
CanExecute
in MVVM is for authorization management but people use it for validation. The best way is to do it in XAML. You will need a converter if you have multiple fields to validate (InverseAndBooleansToBooleanConverter
is my implementation for multiple Booleans values). Here is how to do so:
XAML code(I'm sorry if the XAML code does show because I could have it appear even if I tried):
<Button Name="Button_Test" Content="Test">
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource InverseAndBooleansToBooleanConverter}" Mode="TwoWay">
<Binding ElementName="TextBox_Field1" Path="(Validation.HasError)" />
<Binding ElementName="TextBox_Field2" Path="(Validation.HasError)" />
<Binding ElementName="TextBox_Field3" Path="(Validation.HasError)" />
</MultiBinding>
</Button.IsEnabled>
</Button>
The converter
public class InverseAndBooleansToBooleanConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values.LongLength > 0)
{
foreach (var value in values)
{
if (value is bool && (bool)value)
{
return false;
}
}
}
return true;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Solution 3
Add this to your TextBlock:
Validation.Error="Save_Error"
CodeBehind (xaml.cs):
public partial class MyView : Window
{
private int _noOfErrorsOnScreen = 0;
public MyView()
{
InitializeComponent();
}
private void Save_Error(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
_noOfErrorsOnScreen++;
else
_noOfErrorsOnScreen--;
Save.IsEnabled = _noOfErrorsOnScreen > 0 ? false : true;
}
}
anderi
Updated on September 06, 2021Comments
-
anderi over 2 years
I have couple of textboxes with custom validators:
(I don't mind if "wrong" data is sent back to object (the property is string), I just need to prevent the functionality of a button if there is an error, so if the binding is not the right place for that kind of validation please tell. I just like the Validation.ErrorTemplate support that i can use)<ControlTemplate x:Key="validator" > <DockPanel LastChildFill="True"> <TextBlock DockPanel.Dock="Right" Foreground="Red" FontSize="12pt">!</TextBlock> <Border BorderBrush="Red" BorderThickness="1.0"> <AdornedElementPlaceholder /> </Border> </DockPanel> </ControlTemplate> <TextBox Height="23" Width="150" TextWrapping="Wrap" Validation.ErrorTemplate="{StaticResource validator}"> <TextBox.Text> <Binding Path="StringProperty" UpdateSourceTrigger="LostFocus"> <Binding.ValidationRules> <local:NumbersOnly/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox>
How can I disable specific button if any of the validation error is raised?
<Button Content="DO Work" Height="57" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="234" Click="button1_Click" />