Pergunta

Aqui está a situação ... no nível superior, eu tenho um tabcontrol. Cada página no TabControl consiste em uma caixa de listagem:

<TabControl>
    <TabItem Header="item 1">
        <ListBox>
            <ListBoxItem>sub item 1</ListBoxItem>
            <ListBoxItem>sub item 2</ListBoxItem>
            <ListBoxItem>sub item 3</ListBoxItem>
        </ListBox>
    </TabItem>
    <TabItem Header="item 2">
        <ListBox>
            <ListBoxItem>sub item 1</ListBoxItem>
            <ListBoxItem>sub item 2</ListBoxItem>
        </ListBox>
    </TabItem>
</TabControl>

As caixas de listagem têm um Stackpanel de orientação horizontalmente como seu ListTemplate:

<Style TargetType="ListBox">
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"
                      VisibleChanged="onStackPanelVisibilityChange"
                      Loaded="onStackPanelLoaded"
                      VerticalAlignment="Center" HorizontalAlignment="Center" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
</Style>

Você notará que eu tenho alguns manipuladores de eventos nesse painel de pilha. Esses são para animar os itens dentro do painel de pilha, para que eles desapareçam sequencialmente. Os manipuladores de eventos são implementados como:

void onStackPanelLoaded(object sender, RoutedEventArgs e)
{
    StackPanel panel = sender as StackPanel;

    applySubItemAnimations(panel);
}

void onStackPanelVisibilityChange(object sender, DependencyPropertyChangedEventArgs e)
{
    StackPanel panel = sender as StackPanel;

    if (panel.IsVisible)
    {
        applySubItemAnimations(panel);
    }
}

private void applySubItemAnimations(StackPanel panel)
{
    DoubleAnimation fadeIn = new DoubleAnimation();
    fadeIn.DecelerationRatio = 0.1;
    fadeIn.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500));
    fadeIn.From = 0.0;
    fadeIn.To = 1.0;

    for (int i = 0; i < panel.Children.Count; i++)
    {
        panel.Children[i].Opacity = 0.0;
        fadeIn.BeginTime = new TimeSpan(0, 0, 0, 0, 200 * i + 50);
        panel.Children[i].BeginAnimation(UIElement.OpacityProperty, fadeIn);
    }
}

Na maioria das vezes, isso funciona muito bem. Quando você clica pela primeira vez em (ou carrega) uma guia, os sub-itens no painel da pilha desaparecem em exibição um dos outros. O problema é quando você clica em uma guia que já foi mostrada uma vez antes (ou seja, você está no manipulador de eventos "VisibleChanged" em vez do manipulador "carregado"), todos os itens já são mostrados e eles piscar em ordem, em vez de começar como oculto e sendo mostrando em ordem.

Aqui é onde fica feio. Está linha:

panel.Children[i].Opacity = 0.0;

... faz nada. Se eu passar pelo código no depurador e colocar um relógio em "Painel.Children [i] .Pacity", ele permanece bem em 1.0. Nenhuma exceção ou qualquer coisa. Apenas ... não funciona.

Alguma ideia?

Foi útil?

Solução

Eu tenho um palpite sobre o que pode estar acontecendo: o WPF não remove as animações assim que elas são concluídas; portanto, quando seu código corre através do applySubItemsAnimations Método pela segunda vez, as animações anteriores ainda estão lá. Portanto, você pode tentar remover essas animações passando nulo como segundo parâmetro para

panel.Children[i].BeginAnimation(UIElement.OpacityProperty, null);

Depois, você pode aplicar a nova animação, então o todo for-loop seria assim:

for (int i = 0; i < panel.Children.Count; i++)
{            
    panel.Children[i].Opacity = 0.0;            
    fadeIn.BeginTime = new TimeSpan(0, 0, 0, 0, 200 * i + 50);            
    panel.Children[i].BeginAnimation(UIElement.OpacityProperty, null);        
    panel.Children[i].BeginAnimation(UIElement.OpacityProperty, fadeIn);        
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top