简体   繁体   中英

Doesn't disable the button if the textbox invalid

I have the email text block with validation

<TextBox x:Name="email" Style="{StaticResource emaliStyle}" Grid.Column="2" Grid.Row="2">
                <TextBox.Text>
                    <Binding  Mode="TwoWay" Path="Email"  UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <DataErrorValidationRule ValidatesOnTargetUpdated="False"/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>

 <Style TargetType="TextBox" x:Key="emaliStyle">
        <Setter Property="Width" Value="220"/>
        <Setter Property="Height" Value="30"/>
        <Setter Property="FontSize" Value="18"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="FontSize" Value="20"/>
        <Setter Property="Padding" Value="6,1,1,0"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="{TemplateBinding BorderThickness}" 
                            Background="{TemplateBinding Background}" 
                            CornerRadius="10"
                            SnapsToDevicePixels="True">
                        <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Opacity" TargetName="border" Value="0.56"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Setter x:Name="LoginValidation" Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel LastChildFill="True">
                        <TextBlock DockPanel.Dock="Bottom" Foreground="Maroon" FontSize="8pt"
                                           Text="{Binding ElementName=email, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                        </TextBlock>
                        <AdornedElementPlaceholder Name="email" />
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="BorderBrush" Value="DarkRed" />
                <Setter Property="BorderThickness" Value="2" />
            </Trigger>
        </Style.Triggers>
    </Style>

the validation work and show me the message which I write in viewModel( it doesn't matter)

next step it blocks the button if the field is invalid.

my button and style for it

 <Button x:Name="SignInButton" 
                    Style="{StaticResource SignInButton}"
                    Command="{Binding SignInCommand}" 
                    CommandParameter="{Binding ElementName=This}" 
                    Content="Sign In"/>

 <Style TargetType="Button" x:Key="SignInButton">
        <Setter Property="Background" Value="MidnightBlue"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Width" Value="100"/>
        <Setter Property="Height" Value="40"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border Background="{TemplateBinding Background}" CornerRadius="10">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Height="20" Margin="26,10"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="IsEnabled" Value="False"/>
        <Style.Triggers >
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=(Validation.HasError), ElementName=email}" Value="False"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="IsEnabled" Value="True"/>
            </MultiDataTrigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="LimeGreen"/>
            </Trigger>

        </Style.Triggers>
    </Style>

I write the Multitrigger (later add other textbox fields) to disable my button, but it isn't work.

I try write all with element name Email doesn't help. What i miss? because the error message will show and the field border mark red, bu isn't disable

Your BlockButton() method should return false whenever you want to disable the Button that is bound to the SignInCommand . There is no reason to set the IsEnabled property in a style when you bind to a command.

For the status of the command and the Button to get refeshed, you should raise the CanExecuteChanged event for the command whenever the validation status changes. Most ICommand implementations include a RaiseCanExecuteChanged() method or similar that lets you do this:

private bool _isEmailValid;

private bool BlockButton()
{
    return _isEmailValid && IsAppDeveloper == false && IsEndUser == false;
}

public string this[string columnName]
{
    get
    {
        string error = String.Empty;
        switch (columnName)
        {
            case "Email":
                string s = ValidateModelProperty(Email, columnName);
                _isEmailValid = string.IsNullOrEmpty(s);
                SignInCommand.RaiseCanExecuteChanged();
                return s;
        }

        return error;
    }
}

private string ValidateModelProperty(object value, string propertyName)
{
    ICollection<ValidationResult> validationResults = new List<ValidationResult>();
    ValidationContext validationContext = new ValidationContext(this, null, null) { MemberName = propertyName };
    if (!Validator.TryValidateProperty(value, validationContext, validationResults))
        foreach (ValidationResult validationResult in validationResults)
            return validationResult.ErrorMessage;
    return null;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM