Why is my WPF style trigger not working?

So, I have this in my application. PasswordBox

Xaml

<PasswordBox Name="PB_PASSWORD" Padding="100,0,34,0" FontSize="20" Width="384" Height="34" PasswordChar="█" Password="" HorizontalAlignment="Left" VerticalAlignment="Top" FontFamily="Century Gothic" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" TabIndex="2" PasswordChanged="PB_PASSWORD_PasswordChanged" >
            <PasswordBox.Style>
                <Style BasedOn="{x:Null}" TargetType="{x:Type PasswordBox}">
                    <Setter Property="Background" Value="#FFCCCCCC" />
                    <Setter Property="Foreground" Value="#FFF22613" />
                    <Setter Property="BorderBrush" Value="#FFF22613" />
                    <Setter Property="BorderThickness" Value="0,2,0,2" />
                    <Setter Property="ClipToBounds" Value="true"/>
                    <Setter Property="OverridesDefaultStyle" Value="true"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="PasswordBox">
                                <Grid>
                                    <Border Background="{TemplateBinding Background}"
                                            BorderBrush="{TemplateBinding BorderBrush}"
                                            BorderThickness="{TemplateBinding BorderThickness}">
                                        <ScrollViewer x:Name="PART_ContentHost" Margin="0,-4,0,0" />
                                    </Border>
                                    <TextBlock Name="TB" Text="Password" HorizontalAlignment="Left" Margin="140,0,0,0" VerticalAlignment="Center" Foreground="#FF222222" Opacity="0.3"/>
                                </Grid>
                                <ControlTemplate.Triggers>

                                    <Trigger Property="IsFocused" Value="true">
                                        <Setter TargetName="TB" Property="Text" Value="Password:" />
                                        <Trigger.EnterActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="100,0,34,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="2,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </Trigger.EnterActions>
                                        <Trigger.ExitActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="230,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="140,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="0.3" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </Trigger.ExitActions>
                                    </Trigger>

                                    <Trigger Property="ClipToBounds" Value="false">
                                        <Setter TargetName="TB" Property="Text" Value="Password:" />
                                        <Trigger.EnterActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="100,0,34,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="2,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </Trigger.EnterActions>
                                        <Trigger.ExitActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="230,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="140,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="0.3" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </Trigger.ExitActions>
                                    </Trigger>

                                    <MultiTrigger>
                                        <MultiTrigger.Conditions>
                                            <Condition Property="IsFocused" Value="false" />
                                            <Condition Property="ClipToBounds" Value="true" />
                                        </MultiTrigger.Conditions>
                                        <Setter TargetName="TB" Property="Text" Value="Password" />
                                        <MultiTrigger.EnterActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="230,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="140,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="0.3" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </MultiTrigger.EnterActions>
                                        <MultiTrigger.ExitActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="100,0,34,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="2,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </MultiTrigger.ExitActions>
                                    </MultiTrigger>

                                    <Trigger Property="IsEnabled" Value="false">
                                        <Setter TargetName="TB" Property="Text" Value="DISABLE"/>
                                        <Setter TargetName="TB" Property="Margin" Value="140,0,0,0"/>
                                        <Setter Property="Background" Value="#FFAAAAAA"/>
                                        <Setter Property="Foreground" Value="#FF777777"/>
                                        <Setter Property="BorderBrush" Value="#FF888888" />
                                        <Setter Property="BorderThickness" Value="0,3,0,3" />
                                    </Trigger>

                                    <Trigger Property="Tag" Value="ShowPW">
                                        <Setter Property="Visibility" Value="Hidden"/>
                                    </Trigger>

                                    <Trigger Property="Tag" Value="HidePW">
                                        <Setter Property="Visibility" Value="Visible"/>
                                    </Trigger>

                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                    </Style.Triggers>
                </Style>
            </PasswordBox.Style>
        </PasswordBox>

And I need to change the border color when the password entered is empty.

After changing the BorderColor code, if the PasswordBox password value is changed.
Note. Disabling PasswordBox occurs after PasswordBox.Password is cleared. So it should not matter [I think]. FROM#

    private void PB_PASSWORD_PasswordChanged(object sender, RoutedEventArgs e)
    {
        if (PB_PASSWORD.SecurePassword.Length == 0)
        {   //Password is Empty.
            PB_PASSWORD.ClipToBounds = true;
        }
        else
        {   //Password Not Empty
            PB_PASSWORD.ClipToBounds = false;
        }

        Int32 PWStrength = 0;
        if (PB_PASSWORD.SecurePassword.Length >= 5)
        {
            //A Function that Return int Value between 0-5 depending on how Strong is Password.
            PWStrength = GetPasswordStrength(Marshal.PtrToStringUni(Marshal.SecureStringToGlobalAllocUnicode(PB_PASSWORD.SecurePassword)));
        }
            //Corresponding Colors Are Set as per Returned Integer0=red, 1=Orange+Red, 2=Orange, 3=Yellow, 4=Light Green, 5=Green
        switch (PWStrength)
        {
            case 0:
                {
                    //Following 2 Lines Required to Unfreez Color From Control
                    PB_PASSWORD.Foreground = new SolidColorBrush(CustomColors.PasswordStrengthColors[PWStrength]);
                    PB_PASSWORD.BorderBrush = new SolidColorBrush(CustomColors.PasswordStrengthColors[PWStrength]);

                    ColorAnimation AnimateForegroundColor_0 = new ColorAnimation(CustomColors.PasswordStrengthColors[PWStrength], new Duration(TimeSpan.FromMilliseconds(200)));
                    PB_PASSWORD.Foreground.BeginAnimation(SolidColorBrush.ColorProperty, AnimateForegroundColor_0);
                    ColorAnimation AnimateBorderBrushColor_0 = new ColorAnimation(CustomColors.PasswordStrengthColors[PWStrength], new Duration(TimeSpan.FromMilliseconds(200)));
                    PB_PASSWORD.BorderBrush.BeginAnimation(SolidColorBrush.ColorProperty, AnimateBorderBrushColor_0);
                    break;
                }

            default:
                {
                    ColorAnimation AnimateForegroundColor = new ColorAnimation(CustomColors.PasswordStrengthColors[PWStrength], new Duration(TimeSpan.FromMilliseconds(200)));
                    PB_PASSWORD.Foreground.BeginAnimation(SolidColorBrush.ColorProperty, AnimateForegroundColor);
                    ColorAnimation AnimateBorderBrushColor = new ColorAnimation(CustomColors.PasswordStrengthColors[PWStrength], new Duration(TimeSpan.FromMilliseconds(200)));
                    PB_PASSWORD.BorderBrush.BeginAnimation(SolidColorBrush.ColorProperty, AnimateBorderBrushColor);
                    break;
                }
        }
    }

The password value is not available, so I used the Boolean value to set it, for example: C # ClipToBounds

if (String.IsNullOrEmpty(PB_PASSWORD.Password))
{ PB_PASSWORD.ClipToBounds = true; }
else
{ PB_PASSWORD.ClipToBounds = false; }

This works fine the first time you launch the application.

The problem starts when I change the enable / disable value from the back code, for example, in the following:

FROM#

    private void Button_Click(object sender, RoutedEventArgs e)
    {

        if (PB_PASSWORD.IsEnabled)
        {
            PB_PASSWORD.ClipToBounds = true;
            PB_PASSWORD.Password = "";
            BTN_BROWSE.Focus();
            PB_PASSWORD.MoveFocus(new System.Windows.Input.TraversalRequest(System.Windows.Input.FocusNavigationDirection.Next));
            PB_PASSWORD.IsEnabled = false;
        }
        else
        {
            PB_PASSWORD.IsEnabled = true;
        }
    }

It should look like this after entering the password and then disconnecting:

expected

But it looks like this:

actual

XAML.

+6
1

: - !

MVVM, , " ".

: MVVM Light ( RelayCommand). NuGet. , MVVM. Prism.

1. MVVM?

MVVM (Model - View - ViewModel) - , WPF. , - , , ViewModels - .

, - , , ( , Unit Tests).

1.1 -

- . , ViewModels.

- , - (, , !)

1.2 -

, . , , , ! UserControl ViewModel, , .

1.3 ViewModel

ViewModel - ​​ . , / " ". brain .

2.

:

<Window x:Class="PasswordBoxMVVM.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:PasswordBoxMVVM"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:b="clr-namespace:System.Media;assembly=System"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:PasswordLengthToColorConverter x:Key="passwordLengthToColorConverter" />
</Window.Resources>
<Grid>
    <StackPanel VerticalAlignment="Center">
        <PasswordBox local:PasswordBoxMVVMAttachedProperties.EncryptedPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     IsEnabled="{Binding Path=IsPasswordFieldDisabled, Mode=TwoWay ,UpdateSourceTrigger=PropertyChanged}"
                     FontSize="20" Width="384" Height="34" PasswordChar="█" HorizontalAlignment="Center" FontFamily="Century Gothic" 
                     HorizontalContentAlignment="Left" VerticalContentAlignment="Center" TabIndex="2" Foreground="Red"
                     PasswordChanged="MyPasswordBox_PasswordChanged"
                     IsEnabledChanged="PasswordBox_IsEnabledChanged">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="PasswordChanged">
                    <i:InvokeCommandAction Command="{Binding Path=PasswordChangedCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <PasswordBox.Style>
                <Style TargetType="{x:Type PasswordBox}">
                    <Setter Property="Background" Value="#FFCCCCCC" />
                    <Setter Property="BorderThickness" Value="0,2,0,2" />
                    <Setter Property="BorderBrush" Value="Red" />
                    <Setter Property="ClipToBounds" Value="true"/>
                    <Setter Property="OverridesDefaultStyle" Value="true"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="PasswordBox">
                                <Grid>
                                    <Border Background="{TemplateBinding Background}"
                                            BorderThickness="{TemplateBinding BorderThickness}"
                                            BorderBrush="{TemplateBinding Foreground}">
                                        <ScrollViewer x:Name="PART_ContentHost" Margin="0,-4,0,0"/>
                                    </Border>
                                    <TextBlock Name="TB" Text="Password" HorizontalAlignment="Left" Margin="140,0,0,0" VerticalAlignment="Center"  Opacity="0.3" Foreground="Gray">
                                    </TextBlock>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsFocused" Value="true">
                                        <Setter TargetName="TB" Property="Text" Value="Password:" />
                                        <Trigger.EnterActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="100,0,34,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="2,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </Trigger.EnterActions>
                                        <Trigger.ExitActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="230,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="140,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="0.3" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </Trigger.ExitActions>
                                    </Trigger>

                                    <DataTrigger Binding="{Binding Path=IsPasswordFieldEmpty,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="false">
                                        <Setter TargetName="TB" Property="Text" Value="Password:" />
                                        <DataTrigger.EnterActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="100,0,34,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="2,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </DataTrigger.EnterActions>
                                        <DataTrigger.ExitActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="230,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="140,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="0.3" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </DataTrigger.ExitActions>
                                    </DataTrigger>

                                    <MultiDataTrigger>
                                        <MultiDataTrigger.Conditions>
                                            <Condition Binding="{Binding Path=IsFocused, RelativeSource={RelativeSource Self}}" Value="false" />
                                            <Condition Binding="{Binding Path=IsPasswordFieldEmpty, UpdateSourceTrigger=PropertyChanged}" Value="true" />
                                        </MultiDataTrigger.Conditions>
                                        <Setter TargetName="TB" Property="Text" Value="Password" />
                                        <MultiDataTrigger.EnterActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="230,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="140,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="0.3" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <BackEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </MultiDataTrigger.EnterActions>
                                        <MultiDataTrigger.ExitActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ThicknessAnimation Storyboard.TargetProperty="Padding" To="100,0,34,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <ThicknessAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Margin" To="2,0,0,0" Duration="0:0:0.3">
                                                        <ThicknessAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </ThicknessAnimation.EasingFunction>
                                                    </ThicknessAnimation>
                                                    <DoubleAnimation Storyboard.TargetName="TB" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.3">
                                                        <DoubleAnimation.EasingFunction>
                                                            <SineEase EasingMode="EaseOut"/>
                                                        </DoubleAnimation.EasingFunction>
                                                    </DoubleAnimation>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </MultiDataTrigger.ExitActions>
                                    </MultiDataTrigger>

                                    <Trigger Property="IsEnabled" Value="false">
                                        <Setter TargetName="TB" Property="Text" Value="DISABLE"/>
                                        <Setter TargetName="TB" Property="Margin" Value="140,0,0,0"/>
                                        <Setter Property="Background" Value="#FFAAAAAA"/>
                                        <Setter Property="Foreground" Value="Gray"/>
                                        <Setter Property="BorderBrush" Value="#FF888888" />
                                        <Setter Property="BorderThickness" Value="0,3,0,3" />
                                    </Trigger>
                                    <Trigger Property="Tag" Value="ShowPW">
                                        <Setter Property="Visibility" Value="Hidden"/>
                                    </Trigger>
                                    <Trigger Property="Tag" Value="HidePW">
                                        <Setter Property="Visibility" Value="Visible"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                    </Style.Triggers>
                </Style>
            </PasswordBox.Style>
            <PasswordBox.Triggers>
                <EventTrigger RoutedEvent="PasswordBox.PasswordChanged">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation Storyboard.TargetProperty="(PasswordBox.Foreground).(SolidColorBrush.Color)" 
                                            To="{Binding Path=Password.Length, UpdateSourceTrigger=PropertyChanged, 
                                            Converter={StaticResource passwordLengthToColorConverter}}" Duration="0:0:0.1">
                            </ColorAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="local:PasswordBoxAttachedEvent.HasBeenDisabled">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation Storyboard.TargetProperty="(PasswordBox.Foreground).(SolidColorBrush.Color)" 
                                            To="Gray" Duration="0:0:0.1">
                            </ColorAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="local:PasswordBoxAttachedEvent.HasBeenEnabled">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation Storyboard.TargetProperty="(PasswordBox.Foreground).(SolidColorBrush.Color)" 
                                            To="{Binding Path=Password.Length, UpdateSourceTrigger=PropertyChanged, 
                                            Converter={StaticResource passwordLengthToColorConverter}}" Duration="0:0:0.1">
                            </ColorAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </PasswordBox.Triggers>
        </PasswordBox>
        <Button Width="200" Height="50" Margin="0,50,0,0" Command="{Binding Path=ClickCommand}">Click me</Button>
    </StackPanel>
</Grid>

, , MVVM - , . ViewModel.

:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        var vm = new PasswordViewModel();
        this.DataContext = vm;

        InitializeComponent();
    }

    private void MyPasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
    {
        PasswordBox pBox = sender as PasswordBox;
        PasswordBoxMVVMAttachedProperties.SetEncryptedPassword(pBox, pBox.SecurePassword);    
    }

    private void PasswordBox_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        PasswordBox pBox = sender as PasswordBox;

        if (pBox.IsEnabled == false)
        {
            RoutedEventArgs eventArgs = new RoutedEventArgs(PasswordBoxAttachedEvent.HasBeenDisabledEvent);
            pBox.RaiseEvent(eventArgs);
        }
        if (pBox.IsEnabled == true)
        {
            RoutedEventArgs eventArgs = new RoutedEventArgs(PasswordBoxAttachedEvent.HasBeenEnabledEvent);
            pBox.RaiseEvent(eventArgs);
        }
    }
}

ViewModel - DataContext .

, , .

:. MVVM , , : " MVVM ". ** :) View, - MVVM - .

ViewModel:

namespace PasswordBoxMVVM
{
    public class PasswordViewModel : ViewModelBase
    {
        private bool isPasswordFieldEmpty;
        public bool IsPasswordFieldEmpty
        {
            get { return isPasswordFieldEmpty; }
            set
            {
                isPasswordFieldEmpty = value;
                RaisePropertyChanged();
            }
        }

        private SecureString password;
        public SecureString Password
        {
            get { return password; }
            set
            {
                password = value;
                RaisePropertyChanged();
            }
        }

        private bool isPassWordFieldDisabled;
        public bool IsPasswordFieldDisabled
        {
            get { return isPassWordFieldDisabled; }
            set
            {
                isPassWordFieldDisabled = value;
                RaisePropertyChanged();
            }
        }

        public ICommand ClickCommand { get { return new RelayCommand(doAction, canDoAction); } }
        public ICommand PasswordChangedCommand { get { return new RelayCommand(updatePassword, canUpdatePassword); } }

        public PasswordViewModel()
        {
            // Init conditions, need them to not get null reference at the start.
            isPassWordFieldDisabled = true;
            IsPasswordFieldEmpty = true;
        }

        private void doAction()
        {
            IsPasswordFieldDisabled = !IsPasswordFieldDisabled;
        }

        private bool canDoAction()
        {
            // Replace this with any condition that you need.
            return true;
        }

        private void updatePassword()
        {
            if (Password != null)
            {
                if (Password.Length > 0)
                {
                    isPasswordFieldEmpty = false;
                }
                else
                {
                    isPasswordFieldEmpty = true;
                }
            }
            else
            {
                isPasswordFieldEmpty = true;
            }
        }

        private bool canUpdatePassword()
        {
            // Replace this with any condition that you need. 
            return true;
        }
    }
}

. -, , Password, isPasswordFieldDisabled .. , View, ViewModel.

, ViewModel. View (, ), , ViewModel.

ViewModel, isPasswordBoxDisabled, PasswordBox isEnabled , / PasswordBox - View ViewModel! , ?

namespace PasswordBoxMVVM
{
    class PasswordLengthToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int length = (int)value;
            Color output = Colors.Red;

            if (length >= 0 && length < 5)
                output = Colors.Red;

            else if (length >= 5 && length < 6)
                output = Colors.Orange;

            else if (length >= 6 && length < 7)
                output = Colors.Yellow;

            else if (length >= 7 && length < 8)
                output = Colors.LightGreen;

            else if (length >= 8)
                output = Colors.Green;

            return output;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}

. - . , , , MVVM - ? , , !

Password -

PasswordBox ViewModel. PasswordBox . ! "" PasswordBox, ( ) - , ViewModel.

- , .

+2

Source: https://habr.com/ru/post/1016986/


All Articles