Dynamic Placeholder WPF Animations

192 Views Asked by At

I've made a style for a PasswordBox which allows it to have a placeholder and it works perfectly.
Next thing I did is animating the placeholder to float to the top-left side of the PasswordBox, and it worked.
The only problem is, with different placeholder text length - the animations doesnt seems right.

Here is a picture:
enter image description here

As you can see, the upper PasswordBox is perfectly animated to the current spot, but the lower PasswordBox didn't, because different text-size needs to be animated to different spots.

My question is, how do I achieve this, such that for any PasswordBox, the placeholder will be animated exactly to the start of the input string (above it), like the upper box in the picture?

Here is a showcase of what I'm trying to do (Click the email box): League of Legends registration page


Here is my code:

<!--Registration PasswordBox Style-->
<Style TargetType="{x:Type PasswordBox}" x:Key="RegisterPasswordBox">

    <Setter Property="Padding" Value="10" />
    <Setter Property="Margin" Value="0 10 0 10" />
    <Setter Property="BorderThickness" Value="3" />
    <Setter Property="BorderBrush" Value="Black" />
    <Setter Property="FontSize" Value="20" />
    <Setter Property="Height" Value="50" />
    <Setter Property="Width" Value="250" />
    <Setter Property="HorizontalAlignment" Value="Center" />

    <Setter Property="local:MonitorPasswordProperty.Value" Value="True" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type PasswordBox}">

                <!-- Placeholder Float Animations -->
                <ControlTemplate.Resources>

                    <!-- Enter Animations -->
                    <Storyboard x:Key="enterAnim">
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="placeholder">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="-105">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <QuinticEase EasingMode="EaseInOut"/>
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>

                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="placeholder">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="-20">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <QuinticEase EasingMode="EaseInOut"/>
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>

                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.FontSize)" Storyboard.TargetName="placeholder">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="12">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <QuinticEase EasingMode="EaseInOut"/>
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>

                    </Storyboard>

                    <!-- Exit Animations -->
                    <Storyboard x:Key="exitAnim">
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="placeholder">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="0">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <QuinticEase EasingMode="EaseInOut"/>
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>

                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="placeholder">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="0">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <QuinticEase EasingMode="EaseInOut"/>
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>

                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.FontSize)" Storyboard.TargetName="placeholder">
                            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="20">
                                <EasingDoubleKeyFrame.EasingFunction>
                                    <QuinticEase EasingMode="EaseInOut"/>
                                </EasingDoubleKeyFrame.EasingFunction>
                            </EasingDoubleKeyFrame>
                        </DoubleAnimationUsingKeyFrames>

                    </Storyboard>

                </ControlTemplate.Resources>

                <!-- PasswordBox Content -->
                <Grid>
                    <Border x:Name="border" 
                            BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}"
                            SnapsToDevicePixels="True">
                        <ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                    </Border>

                    <TextBlock IsHitTestVisible="False"
                               Text="{TemplateBinding Tag}"
                               x:Name="placeholder"
                               Padding="{TemplateBinding Padding}"
                               VerticalAlignment="Center"
                               HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                               Foreground="DarkSlateGray">

                        <TextBlock.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </TextBlock.RenderTransform>

                    </TextBlock>

                </Grid>

                <!-- Triggers -->
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Opacity" TargetName="border" Value="0.56"/>
                    </Trigger>

                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" TargetName="border" Value="#FFACAC3D"/>
                    </Trigger>

                    <Trigger Property="IsKeyboardFocused" Value="True">
                        <Setter Property="BorderBrush" TargetName="border" Value="#FFACAC3D"/>
                    </Trigger>

                    <!-- Placeholder Float Triggers -->
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="local:MonitorPasswordProperty.Value" Value="True" />
                            <Condition Property="IsMouseOver" Value="False" />
                            <Condition Property="IsKeyboardFocused" Value="False" />
                        </MultiTrigger.Conditions>

                        <MultiTrigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource exitAnim}" />
                        </MultiTrigger.EnterActions>

                        <MultiTrigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource enterAnim}" />
                        </MultiTrigger.ExitActions>

                    </MultiTrigger>

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

</Style>
0

There are 0 best solutions below