开发者

Accessing a style's storyboard of a button

My problem is that I have a Button and I want to access the Storyboard, which is a part of the assigned style.

<Button x:Name="pictureFolderButton" Content="Pictures" Style="{StaticResource ImageTileButtonStyle}" Click="pictureFolderButton_Click" />

The style is very comprehensive so I'll post only a part of it:

<Style x:Key="ImageTileButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetTy开发者_高级运维pe="{x:Type Button}">
                        <ControlTemplate.Resources>
                            <Storyboard x:Key="OnLoaded1"/>
                        </ControlTemplate.Resources>
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    ...
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="AnimationStates">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition GeneratedDuration="0:0:1">
                                            <VisualTransition.GeneratedEasingFunction>
                                                <CircleEase EasingMode="EaseOut"/>
                                            </VisualTransition.GeneratedEasingFunction>
                                        </VisualTransition>
                                    </VisualStateGroup.Transitions>

                                    <VisualState x:Name="ExpandedFull">
                                        <Storyboard x:Name="expandStoryBoard" >
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="border1">

                                                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="130"/>
                                                <EasingDoubleKeyFrame KeyTime="0:0:3" Value="130"/>
                                                <EasingDoubleKeyFrame KeyTime="0:0:4" Value="47"/>
                                                <EasingDoubleKeyFrame KeyTime="0:0:8" Value="47"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>

                            <ContentPresenter RecognizesAccessKey="True" VerticalAlignment="Stretch" Margin="0,47,0,0" />

                        </Grid>

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

I just want to get notified when the "ExpandedFull" animation has ended. Therefore, I thought I have to get the "expandStoryBoard" programmatically and add a Completed event handler.

The only thing I got working is to access the button's style at runtime:

Style style = pictureFolderButton.FindResource("ImageTileButtonStyle") as Style;

How do I have to proceed? Thank you very much!


In theory you should be able to go down the visual and logical tree of your button to get to the storyboard, but that is rather tedious, if you name the Grid in the template "grid", something like the following might work:

Grid grid = pictureFolderButton.FindName("grid") as Grid;
IList groups = VisualStateManager.GetVisualStateGroups(grid);
VisualStateGroup targetGroup = null;
foreach (var group in groups)
{
    if (group is VisualStateGroup && (group as VisualStateGroup).Name == "AnimationStates")
    {
        targetGroup = group as VisualStateGroup;
        break;
    }
}
if (targetGroup != null)
{
    IList states = targetGroup.States;
    VisualState targetState = null;
    foreach (var state in states)
    {
        if (state is VisualState && (state as VisualState).Name == "ExpandedFull")
        {
            targetState = state as VisualState;
            break;
        }
    }
    if (targetState != null)
    {
        targetState.Storyboard.Completed += new EventHandler(Expansion_Completed);
    }
    else throw new Exception("VisualState not found.");
}
else throw new Exception("VisualStateGroup not found.");

Another way that comes to mind is extracting your storyboard to a resource, but i am not sure if this will have any side effects, i.e.:

<ControlTemplate.Resources>
    ...
    <Storyboard x:Key="expandStoryBoard" x:Name="expandStoryBoard">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="border1">
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="130"/>
            <EasingDoubleKeyFrame KeyTime="0:0:3" Value="130"/>
            <EasingDoubleKeyFrame KeyTime="0:0:4" Value="47"/>
            <EasingDoubleKeyFrame KeyTime="0:0:8" Value="47"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</ControlTemplate.Resources>
...
<VisualState x:Name="ExpandedFull" Storyboard="{StaticResource expandStoryBoard}"/>

Then you should be able to use FindResource on the button to get the storyboard.

Hopefully some of that works or at least helps a bit.


Just try with this with StoryBoard name "OnLoaded1":

 <Button Height="75" Width="120" Style="{StaticResource ImageTileButtonStyle}" Click="Button_Click" >Hello</Button>


  private void Button_Click(object sender, RoutedEventArgs e)
    {
        Button btn=(Button)sender;

        Storyboard stb = btn.TryFindResource("OnLoaded1") as Storyboard;

    }


If you add the Storyboard to the resources, you can set the event handler for the Timeline.Completed event in the XAML file and implement the handler in the corresponding class.

Define the Storyboard in the Resources section of your control like this:

<UserControl.Resources>
  <Storyboard x:Key="expandStoryBoard" Completed="OnExpandCompleted"> ... </Storyboard>
  ...
</UserControl.Resources>

Reference the Storyboard as a static resource:

<VisualState x:Name="ExpandedFull" Storyboard="{StaticResource expandStoryBoard}" />

Implement the Completed event handler in the corresponding class:

void OnExpandCompleted(object sender, EventArgs e)
{
   ...
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜