Willy
Willy

Reputation: 10660

C# WPF Animated label content is not being shown

I am trying to animate the content of a label in order to do:

Loading
Loading.
Loading..
Loading...

again:

Loading
Loading.
Loading..
Loading...

and so on like in this example.

Below the code:

<Label Grid.Row="2" x:Name="CurrentTask" 
       FontFamily="Microsoft Sans Serif" FontSize="18" FontStyle="Italic" FontWeight="Bold" 
       Foreground="White" Content="Loading">
    <Label.Template>
        <ControlTemplate>
            <ControlTemplate.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Content" Storyboard.TargetProperty="Content" Duration="00:00:00.8" RepeatBehavior="Forever">
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00.0" Value="Loading"/>
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00.2" Value="Loading."/>
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00.4" Value="Loading.."/>
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00.6" Value="Loading..."/>
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Label.Template>
</Label>

The problem is that label content is not visible in the wpf window. It is not being shown. What am I doing wrong?

Also in the lines of type:

<DiscreteObjectKeyFrame KeyTime="00:00:00.0" Value="Loading"/>

Instead of hard-coding the value I would like to concatenate the label content to the dots, how can I do this? I do not want to repeat the "Loading" string in each DiscreteObjectKeyFrame.

UPDATE: Instead of raise trigger on IsEnabled=True, I have used label.loaded as below for example in the case of applying label style:

    <Label Grid.Row="2" x:Name="CurrentTask" 
           FontFamily="Microsoft Sans Serif" FontSize="18" FontStyle="Italic"  
           Foreground="White" Content="Loading">
        <Label.Style>
            <Style TargetType="Label">
                <Style.Triggers>
                    <EventTrigger RoutedEvent="Label.Loaded">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Duration="00:00:00.8" RepeatBehavior="Forever">
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00.0" Value="Loading"/>
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00.2" Value="Loading."/>
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00.4" Value="Loading.."/>
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00.6" Value="Loading..."/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                </Style.Triggers>
            </Style>
        </Label.Style>
    </Label>

Upvotes: 2

Views: 190

Answers (1)

Clemens
Clemens

Reputation: 128145

Besides the Triggers, your ControlTemplate is empty, so obviously nothing is shown.

You could add a ContentPresenter, and also remove the Storyboard.TargetName. It looks also odd that your Trigger acts on IsEnabled set to false.

<Label.Template>
    <ControlTemplate TargetType="Label">

        <ContentPresenter/>

        <ControlTemplate.Triggers>
            <Trigger Property="IsEnabled" Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Duration="00:00:00.8" RepeatBehavior="Forever">
                                <DiscreteObjectKeyFrame KeyTime="00:00:00.0" Value="Loading"/>
                                <DiscreteObjectKeyFrame KeyTime="00:00:00.2" Value="Loading."/>
                                <DiscreteObjectKeyFrame KeyTime="00:00:00.4" Value="Loading.."/>
                                <DiscreteObjectKeyFrame KeyTime="00:00:00.6" Value="Loading..."/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</Label.Template>

However, what you actually might want to have is a Style Trigger instead of a ControlTemplate Trigger:

<Label ...>
    <Label.Style>
        <Style TargetType="Label">
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Duration="00:00:00.8" RepeatBehavior="Forever">
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00.0" Value="Loading"/>
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00.2" Value="Loading."/>
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00.4" Value="Loading.."/>
                                    <DiscreteObjectKeyFrame KeyTime="00:00:00.6" Value="Loading..."/>
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
</Label>

For the repeated "Loading" string in the Content, just use two Labels, one with a fixed "Loading" string, the other with the dots, and adjust their Padding. Or better, two TextBlocks:

<StackPanel Orientation="Horizontal">
    <TextBlock Text="Loading"/>
    <TextBlock>
        <TextBlock.Style>
            <Style TargetType="TextBlock">
                <Style.Triggers>
                    <Trigger Property="IsEnabled" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Text" Duration="00:00:00.8" RepeatBehavior="Forever">
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00.0" Value=""/>
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00.2" Value="."/>
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00.4" Value=".."/>
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00.6" Value="..."/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</StackPanel>

Upvotes: 2

Related Questions