Matthias Herrmann
Matthias Herrmann

Reputation: 2790

Create Custom Control with Storyboard XAML

I created a custom Control in a Windows 10 Universal App project, which is containing a Storyboard. The Code of the storyboard is looking like this:

<Storyboard x:Key="StatisticUpdateAnnimation">
        <DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="(RingSlice.EndAngle)" Storyboard.TargetName="ringSlice">
        <EasingDoubleKeyFrame KeyTime="0" Value="45"/>
        <EasingDoubleKeyFrame KeyTime="0:0:2.2" Value="{Binding Angle}">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase EasingMode="EaseIn"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
    </DoubleAnimationUsingKeyFrames>
    </Storyboard>

As you can see the x:Key = "StatisticUpdateAnnimation, the storyboard should be triggered only manually in C# code so I do not know how to Play this Storyboard after I created the Custom User Control in the Mainpage file like this:`

local:ProgressRing  x:Name="Progress" Margin="7"  VerticalAlignment="Top" HorizontalAlignment="Center" Tapped="ProgressRing_Tapped"/>

The style is like this

 <Style TargetType="local:RingPresenter" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:RingPresenter">
                <Grid>
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Mode=TwoWay, ElementName=Representor, Path=EndAngle}" FontFamily="Vladimir Script" FontSize="48"></TextBlock>
                    <helper:RingSlice InnerRadius="100" Radius="150"  StartAngle="0" EndAngle="{TemplateBinding Angle}"  Fill="DarkCyan" x:Name="ringSlice">
                    </helper:RingSlice>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

How can I access my storyboard?

Upvotes: 2

Views: 465

Answers (1)

Grace Feng
Grace Feng

Reputation: 16652

Since I don't know what is your ProgressRing.HelperClasser, here I wrote a sample to show one method using Storyboard inside of the CustomControl. As we know, CustomControl is template control inside of the ResourceDictionary, we can for example use Storyboard inside of the ControlTemplate like this:

Generic.xaml

<Style TargetType="local:ProgressRing">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:ProgressRing">
                <Grid x:Name="RootGrid">
                    <Grid.Resources>
                        <Storyboard x:Key="std">
                            <ColorAnimation Storyboard.TargetName="brush" Storyboard.TargetProperty="Color"
                                            Duration="0:0:2" From="LightBlue" To="Red" AutoReverse="True" />
                        </Storyboard>
                    </Grid.Resources>
                    <Ellipse Width="100" Height="100">
                        <Ellipse.Fill>
                            <SolidColorBrush x:Name="brush" />
                        </Ellipse.Fill>
                    </Ellipse>
                    <TextBlock Text="111" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

And in the cs file of this Custom control:

public ProgressRing()
{
    this.DefaultStyleKey = typeof(ProgressRing);
    this.Loaded += ProgressRing_Loaded;
}

private void ProgressRing_Loaded(object sender, RoutedEventArgs e)
{
    StoryboardPlay();
}

public void StoryboardPlay()
{
    var rootGrid = this.GetTemplateChild("RootGrid") as Grid;
    var std = rootGrid.Resources["std"] as Storyboard;
    std.Begin();
}

I played this Storyboard here once it is loaded. Here the Control.GetTemplateChild method is useful, it helps find the named element in the instantiated ControlTemplate visual tree. Then you can get the resource inside this element.

Now if you use this custom control like this:

<local:ProgressRing  x:Name="Progress" Margin="7"  VerticalAlignment="Top" HorizontalAlignment="Center" Tapped="ProgressRing_Tapped" />
<Button VerticalAlignment="Bottom" Content="Click to play storyboard" Click="Button_Click" />

Now you can get the storyboard to play like this:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Progress.StoryboardPlay();
}

Upvotes: 1

Related Questions