Доступ к раскадровке стиля кнопки - PullRequest
3 голосов
/ 12 марта 2011

Моя проблема в том, что у меня есть Button, и я хочу получить доступ к Storyboard, который является частью назначенного стиля.

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

Стиль очень всеобъемлющий, поэтому я опубликую только его часть:

<Style x:Key="ImageTileButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{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>

Я просто хочу получить уведомление, когда анимация "ExpandedFull" закончилась. Поэтому я подумал, что мне нужно программно получить "expandStoryBoard" и добавить обработчик событий Completed .

Единственное, что я получил, это доступ к стилю кнопки во время выполнения:

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

Как мне поступить? Большое спасибо!

Ответы [ 3 ]

2 голосов
/ 12 марта 2011

Теоретически у вас должна быть возможность пройтись по визуальному и логическому дереву вашей кнопки, чтобы добраться до раскадровки, но это довольно утомительно, если вы назовете Grid в шаблоне "grid", что-то вроде следующего может работать:

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.");

Еще один способ, который приходит на ум, - извлечь вашу раскадровку на ресурс, но я не уверен, будут ли у нее какие-либо побочные эффекты, например:

<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}"/>

Тогда вы сможете использовать FindResource на кнопке, чтобы получить раскадровку.

Надеюсь, кое-что из этого работает или хотя бы немного поможет.

2 голосов
/ 12 марта 2011

Просто попробуйте это с StoryBoard именем "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;

    }
0 голосов
/ 07 марта 2013

Если вы добавите Storyboard к ресурсам, вы можете установить обработчик событий для события Timeline.Completed в файле XAML и реализовать обработчик в соответствующем классе.

Определите Storyboard в разделе ресурсов вашего элемента управления следующим образом:

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

Ссылка на Storyboard как статический ресурс:

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

Реализация обработчика событий Completed в соответствующем классе:

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