c# - 如何在WPF中使用动画使文本 block 向上移动( float )

标签 c# wpf visual-studio xaml

我想知道如何在 Xaml (WPF) 中使用动画使文本 block 向上移动(或者更准确地说是向上 float )。

假设我有登录屏幕,并且有两个文本 block :用户名和密码。当我单击文本 block (用户名或密码)时,文本 block 将向上移动(向上 float )并带有动画效果,直到文本 block 越过框的边界线,然后文本 block 将停止移动。在同一个动画中,文本 block 中的文本字体大小变小(例如,从 12px 到 6px)。

此外,在同一动画中,当文本向上移动时,我想为文本添加模糊效果,模糊效果在文本 block 向上 float 时开始,并在文本 block 越过框线时恢复正常。

example of floating textblock

最后,当我在登录屏幕上的其他地方单击时,如果框中没有任何内容,文本 block 将返回到起点位置。

我发现了类似的东西 here

这是我的代码(行不通) Xaml:

x:Class="tester.Window1"
    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:tester"
    mc:Ignorable="d"
    Title="Window1" Height="400" Width="600" >
<Grid>


     <Border Margin="246,164,184,175" BorderThickness="1,1,1,1" BorderBrush="Black" >
            <Label
                Name="Two"
                Margin="-1,-11,61,-1"
                Width="100" Height="36" FontSize="20"  
                VerticalAlignment="Top" VerticalContentAlignment="Top" 
                Foreground="Blue"  >                
                Name
                <Label.Effect>
                    <BlurEffect Radius="0" x:Name="BlurEffect2"/>
                </Label.Effect>
                <Label.Triggers>
                    <EventTrigger 
                        RoutedEvent="Label.MouseLeftButtonDown">
                        <BeginStoryboard>
                            <Storyboard x:Name="FirstLabelName" Completed="FirstLabelName_Completed" >
                                <DoubleAnimation
                                    Storyboard.TargetName="Two"
                                    Storyboard.TargetProperty="(Label.Height)"
                                    To="20.0" Duration="0:0:0.3"
                                    AutoReverse="False" />
                                <DoubleAnimation
                                    Storyboard.TargetName="Two"
                                    Storyboard.TargetProperty="(FontSize)"
                                    To="16" Duration="0:0:0.3"
                                    AutoReverse="False" />
                                <DoubleAnimation
                                    Storyboard.TargetName="BlurEffect2"
                                    Storyboard.TargetProperty="Radius"
                                    To="10" Duration="0:0:0.3"
                                    AutoReverse="False" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Label.Triggers>                
            </Label>
        </Border>
        <Border Margin="0,0,20,50"  Height="30" Width="100" BorderThickness="1,1,1,1" BorderBrush="White"  >
            <Label
                Name="one"
                Margin="9,-1"
                Width="80" Height="30" FontSize="16" 
                VerticalAlignment="Top" VerticalContentAlignment="Top"
                Foreground="Blue" Visibility="Hidden">
                Name
                <Label.Effect>
                    <BlurEffect Radius="10" x:Name="BlurEffect"/>
                </Label.Effect>

                <Label.Style>
                    <Style TargetType="Label">
                        <Style.Triggers>
                            <Trigger Property="Visibility" Value="Visible">
                                <Trigger.EnterActions>
                                    <BeginStoryboard x:Name="StoryBoardOne">
                                        <Storyboard x:Name="Effect1"  >
                                            <DoubleAnimation
                                    Storyboard.TargetName="one"
                                    Storyboard.TargetProperty="(Label.Height)"
                                    To="30.0" Duration="0:0:0.5"
                                    AutoReverse="False"  />
                                            <DoubleAnimation
                                    Storyboard.TargetName="one"
                                    Storyboard.TargetProperty="(FontSize)"
                                    To="12" Duration="0:0:0.3"
                                    AutoReverse="False"  />
                                            <DoubleAnimation
                                    Storyboard.TargetName="BlurEffect"
                                    Storyboard.TargetProperty="Radius"
                                    To="0" Duration="0:0:0.5"
                                    AutoReverse="False"  />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </Trigger.EnterActions>
                                <Trigger.ExitActions>
                                    <StopStoryboard BeginStoryboardName="StoryBoardOne"></StopStoryboard>
                                </Trigger.ExitActions>                                    
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Label.Style>               

            </Label>
        </Border>
    </Grid>
</Window>

返回:

private void FirstLabelName_Completed(object sender, EventArgs e)
        {
            Two.Visibility = Visibility.Hidden;            
            one.Visibility = Visibility.Visible;
        }

最佳答案

因此,您正在寻找的内容被粗略地称为内联标签输入。它们并不难,但如果你想要真正的光滑的,那么定制控制模板确实需要一些努力。您需要创建 Storyboard 动画并通过触发器中的进入/退出操作触发它们。除非您正在使用 VisualStateManager,否则您将通过 VisualState 触发动画。

这是一个快速的 PoC 示例,说明您如何做类似的事情来开始。然而,我确实故意留下了一些收尾工作,以避免只交出一个完整的解决方案。除了应该有足够的快速完成和调整以满足您的需求。希望这会有所帮助,干杯!

结果(以断断续续的 .gif 形式提供视觉辅助);

enter image description here

...这是从默认 wpf TextBox 模板制作的快速示例。

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <StackPanel.Resources>
        <SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
        <SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
        <SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
        <Style x:Key="CW-Inline-TextBox" TargetType="{x:Type TextBox}">
            <Setter Property="Height" Value="35"/>
            <Setter Property="Width" Value="150"/>
            <Setter Property="Margin" Value="0,25,0,0"/>
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="AllowDrop" Value="true"/>
            <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <ControlTemplate.Resources>
                            <Storyboard x:Key="CW-Inline-input-example">
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="textBlock">
                                    <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="-6.667">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <QuinticEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="textBlock">
                                    <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="-25.733">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <QuinticEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                                <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="textBlock">
                                    <EasingColorKeyFrame KeyTime="0:0:0.6" Value="#FF0285BA"/>
                                </ColorAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.FontWeight)" Storyboard.TargetName="textBlock">
                                    <DiscreteObjectKeyFrame KeyTime="0:0:0.3">
                                        <DiscreteObjectKeyFrame.Value>
                                            <FontWeight>Bold</FontWeight>
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </ControlTemplate.Resources>

                        <Grid>

                            <Border x:Name="border" Grid.Row="1"
                            BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
                            Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                                <ScrollViewer x:Name="PART_ContentHost" Focusable="false" 
                                      HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                            </Border>

                            <TextBlock x:Name="textBlock" Text="{TemplateBinding Tag}"
                                   VerticalAlignment="Center" Margin="8,0"
                                   Foreground="Gray" RenderTransformOrigin="0.5,0.5">
                                <TextBlock.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform/>
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform/>
                                    </TransformGroup>
                                </TextBlock.RenderTransform>
                            </TextBlock>

                        </Grid>

                        <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="{StaticResource TextBox.MouseOver.Border}"/>
                            </Trigger>
                            <Trigger Property="IsKeyboardFocused" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>

                                <Trigger.EnterActions>
                                    <BeginStoryboard Storyboard="{StaticResource CW-Inline-input-example}" />
                                </Trigger.EnterActions>
                                <!--
                            <Trigger.ExitActions>
                                // In case you wanted to do something cool on exit too..
                            </Trigger.ExitActions>
                            -->
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
                        <Condition Property="IsSelectionActive" Value="false"/>
                    </MultiTrigger.Conditions>
                    <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                </MultiTrigger>
            </Style.Triggers>
        </Style>
    </StackPanel.Resources>

    <TextBox Tag="Your label"
             Height="35" Width="150" FontSize="20"
             Style="{DynamicResource CW-Inline-TextBox}"/>

    <TextBox Tag="Your other label"
             Style="{DynamicResource CW-Inline-TextBox}"/>

    <TextBox Tag="Another Instance"
             Height="75" Width="150" FontSize="15"
             Style="{DynamicResource CW-Inline-TextBox}"/>

</StackPanel>

很抱歉,我很忙,没能尽快回复。享受:)

关于c# - 如何在WPF中使用动画使文本 block 向上移动( float ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41789394/

相关文章:

c# - 如何命名我制作的新 Excel 工作表并将其放在所有工作表的末尾?

c++ - Visual Studio 2013 : How to open basic C file

c# - 将变量转换为仅在运行时已知的类型?

c# NetworkStream 的 write() 和 read()

c# - 注册表.CurrentUser.OpenSubKey

.net - Visual Studio 项目的依赖关系图

visual-studio - 将方法调用替换为另一个

c# - 有没有办法假装来自切换按钮的 handleCheck 从未发生过?

c# - 从静态上下文更改非静态对象

c# - 如何开始使用 SQlite 和 .net 4.0?