BAndrei
BAndrei

Reputation: 249

XAML, Disable button when there are some errors inside the controls from ListView

I have some problems with disabling one button if some controls inside a ListView have validation errors. It works for me when i check for errors directly from a control out of a ListView. Like in code below:

<Button.Style>
                    <Style TargetType="Button" BasedOn="{StaticResource MaterialDesignRaisedButton}">
                        <Setter Property="IsEnabled" Value="False" />
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding Path=(Validation.HasError), ElementName=TextBoxName}" Value="False" />                                        
                                </MultiDataTrigger.Conditions>
                                <Setter Property="IsEnabled" Value="True" />
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </Button.Style>

And the control has:

<TextBox Name="TextBoxName"
                m:HintAssist.Hint="Title"
                m:HintAssist.IsFloating="True">
                <TextBox.Text>
                    <Binding Mode="TwoWay" Path="Test.Item1.Name" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:NotEmptyValidationRule ValidatesOnTargetUpdated="True" />
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>

So this works for me. But when i want to look inside of a ListView that has 6 controls(textboxes and comboboxes), i need to check if only two of them have errors.

How to find if only two controls from inside of a ListView have errors?

PS: I am using MVVM pattern. ListView has ItemTemplate, DataTemplate, and inside - controls like TextBox and ComboBox:

<ListView Name="ListViewTests" HorizontalAlignment="Center" Grid.Row="1" ItemsSource="{Binding SelectedActiveTests}"
                  ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                  ScrollViewer.VerticalScrollBarVisibility="Auto"
                  ScrollViewer.CanContentScroll="False">
            <ListView.ItemTemplate>
                <DataTemplate>

Please help, and sorry for my bad english...

Upvotes: 0

Views: 439

Answers (1)

S. Spindler
S. Spindler

Reputation: 546

one solution to your problem is to use a Command. When you bind a RelayCommand to your button, it automatically gets disabled if CanExecute returns false. So you can do your validation in the CanExecute method of your command. Something like this:

MyCommand = new RelayCommand(arg => ExecuteCommandAction(), arg => IsValid())

Update

Note that I used Microsoft EnterpriseLibrary for Validation! (https://msdn.microsoft.com/en-us/library/ff664451(v=pandp.50).aspx)

Define a command that checks for validation errors:

SaveAndCloseCommand = new RelayCommand(SaveAndCloseCommandExecute, arg => this.IsValid());

IsValid is a ViewModel method:

public bool IsValid()
{
    var validator = ValidationFactory.CreateValidator<YourViewModel>();
    return validator.Validate(this).IsValid;
}

Bind to your button:

<Button x:Name="SaveAndCloseButton" Command="{Binding SaveAndCloseCommand}" />

Your ViewModel has to contain validated properties like this:

[ValidatorComposition(CompositionType.And)]
[StringLengthValidator(1, 100)]
[RegexValidator(@"[^ ]")]
public string FirstName { ... }

TextField looks like this:

<TextBox Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}"             
         vab:Validate.ValidatesOnTargetUpdated="True" 
         vab:Validate.BindingForProperty="Text" />

Possible IsValid method to check your list items:

public bool IsValid()
{
    var allListItemsValid = myList.All(x => x.IsValid());   

    var validator = ValidationFactory.CreateValidator<YourViewModel>();
    return validator.Validate(this).IsValid && allListItemsValid;
}

Your list items should be ViewModels wich contains its validation, so you can check each item whether its valid or not.

Upvotes: 2

Related Questions