无法获得(相当简单)WPF动画工作

时间:2011-09-14 18:07:59

标签: wpf xaml animation

我正在尝试在WPF中设置一个动画消息面板,但到目前为止还没有成功。

情况就是这样:

  1. 我有一个StackPanel的用户控件,其中ItemsControl绑定到控件的View Model对象(ViewModel.Messages)中的(可观察的)集合。
  2. 当我需要向用户显示消息时,我会将这些消息(作为MessageVM实例)添加到可观察集合中。
  3. ItemsControl的可见性绑定到名为ViewModel.CountVisibleMessages的整数属性,并且有一个转换器负责将0转换为Visibility.Hidden,将正值转换为Visibility.Visible。< / p>

    这很好用。当消息添加到集合时,StackPanel会自动变为可见,并且当用户(或计时器)删除它被隐藏的最后一条消息时。 StackPanel高度会自动调整以适应所有消息。

    为了让一切看起来更漂亮,如果StackPanel使用运行300毫秒的动画调整自身大小,我会更喜欢它。 (最终我还希望它能加速和减速,但这超出了我的目标。

    我现在已经进行了几个小时的实验,但我觉得我甚至都没有接近。 以下是我目前的(当时甚至没有接近工作)XAML:

    <StackPanel Orientation="Vertical" 
                    VerticalAlignment="Top" 
                    Visibility="{Binding CountVisibleMessages, Converter={StaticResource IntToVisibility}}"
                    Height="Auto"
                    Background="{DynamicResource HmiBackColorLightBrush}">
            <StackPanel.Style>
                <Style>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding CountVisibleMessagesChanged}" Value="True" ><!-- I suppose I shopuld've used a Routed Event here but I just needed to get it triggered -->
                            <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation
                                            Storyboard.TargetProperty="Margin.Bottom"
                                            From="100" <!-- Just a made up value to test the concept -->
                                            To="0"
                                            Duration="0:0:0:3"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </StackPanel.Style>
            <ItemsControl ItemsSource="{Binding Messages}" >
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border Style="{DynamicResource Message}">
                            <Grid >
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="15" />
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Text="{Binding Text}" Margin="3" Style="{Binding MessageType, Converter={StaticResource MessageTypeToStyle}, ConverterParameter={x:Type TextBlock}}" /> <!-- using dynamic styling here -->
                                <RadioButton Grid.Column="1" Style="{DynamicResource HmiCloseMessageButton}" IsChecked="{Binding IsVisible, Converter={StaticResource BoolToVisibility}, ConverterParameter=true}" />
                            </Grid>
                        </Border>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>
    

    (我确实意识到上面的XAML不会让StackPanel慢慢地自动调整大小。这只是一个让发生任何事情的实验)。

    我认为这不是太困难(这在很多程序中都是非常标准的UI行为)所以如果有人能指出我正确的方向,我会很感激。

    干杯

2 个答案:

答案 0 :(得分:0)

您确定要调整底部边距吗?堆栈面板VerticalAlignment是顶部。如果要更改高度,请将StoryBoard属性绑定到高度。你知道你的StoryBoard是在解雇吗?

答案 1 :(得分:0)

关键点ExitActions是基于EnterAction的dataTrigger动画所必需的。所以以下似乎在我的情况下工作....

<StackPanel Grid.Row="0" Height="100" x:Name="MyGrid">
   <StackPanel.Style>
      <Style>
         <Style.Triggers>
            <DataTrigger
               Binding="{Binding ElementName=MyCheckBox,
                                 Path=IsChecked}" Value="True">
               <DataTrigger.EnterActions>
                  <BeginStoryboard>
                     <Storyboard>
                        <DoubleAnimation 
                           Storyboard.Target="{Binding
                             RelativeSource={RelativeSource
                               AncestorType={x:Type 
                                 StackPanel}},
                             BindsDirectlyToSource=True}"
                           Storyboard.TargetProperty="Height"
                           From="100" 
                           To="200"
                           Duration="0:0:1"/>
                     </Storyboard>
                  </BeginStoryboard>
               </DataTrigger.EnterActions>
               <DataTrigger.ExitActions>
                  <BeginStoryboard>
                     <Storyboard>
                        <DoubleAnimation 
                           Storyboard.Target="{Binding
                              RelativeSource={RelativeSource
                                 AncestorType={x:Type 
                                   StackPanel}},
                              BindsDirectlyToSource=True}"
                              Storyboard.TargetProperty="Height"
                              To="100"
                              Duration="0:0:1"/>
                     </Storyboard>
                  </BeginStoryboard>
               </DataTrigger.ExitActions>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </StackPanel.Style>
 </StackPanel>
 <CheckBox x:Name="MyCheckBox" Grid.Row="1" />

如果有帮助,请告诉我。