Не отключает кнопку, если текстовое поле недействительно - PullRequest
1 голос
/ 19 июня 2019

У меня есть текстовый блок электронной почты с проверкой

<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>

проверка работы и показать мне сообщение, которое я пишу в viewModel (это не имеет значения)

следующий шаг блокирует кнопку, если поле недействительно.

моя кнопка и стиль для нее

 <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>

Я пишу Multitrigger (позже добавлю другие поля текстового поля), чтобы отключить мою кнопку, но это не работает.

Я пытаюсь написать все с именем элемента Email не помогает. Что я скучаю? потому что сообщение об ошибке будет отображаться, а граница поля помечается красным, но не отключено

1 Ответ

1 голос
/ 20 июня 2019

Ваш метод BlockButton() должен возвращать false всякий раз, когда вы хотите отключить Button, связанный с SignInCommand. При привязке к команде нет смысла устанавливать свойство IsEnabled в стиле.

Чтобы статус команды и Button были обновлены, вы должны вызывать событие CanExecuteChanged для команды всякий раз, когда изменяется статус проверки. Большинство реализаций ICommand включают метод RaiseCanExecuteChanged() или аналогичный, который позволяет вам сделать это:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...