代码之家  ›  专栏  ›  技术社区  ›  Metro Smurf

WPF:绑定更改时如何触发事件触发器(或动画)?

  •  2
  • Metro Smurf  · 技术社区  · 16 年前

    我们有一个简单的动画,当选中或取消选中ToggleButton时运行(展开ListView的高度,然后折叠ListView的高度)。如何触发事件触发器(或动画) <Storyboard x:Key="CommentsCollapse"> 当数据上下文绑定在 x:Name="DetailsGrid" 以下XAML中的网格?

    换句话说,每当“detailsgrid”的绑定更改时,我们希望触发“commentsCollapse”故事板,以确保ListView返回到其折叠状态。

    <Page
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Width="800"
       Height="400">
       <Page.Resources>
          <Storyboard x:Key="CommentsExpand">
             <DoubleAnimationUsingKeyFrames
                BeginTime="00:00:00"
                Storyboard.TargetName="CommentsListView"
                Storyboard.TargetProperty="(FrameworkElement.Height)">
                <SplineDoubleKeyFrame KeyTime="00:00:00.200" Value="300"/>
             </DoubleAnimationUsingKeyFrames>
          </Storyboard>
          <Storyboard x:Key="CommentsCollapse">
             <DoubleAnimationUsingKeyFrames
                BeginTime="00:00:00"
                Storyboard.TargetName="CommentsListView"
                Storyboard.TargetProperty="(FrameworkElement.Height)">
                <SplineDoubleKeyFrame KeyTime="00:00:00.200" Value="75"/>
             </DoubleAnimationUsingKeyFrames>
          </Storyboard>
       </Page.Resources>
       <Page.Triggers>
          <EventTrigger RoutedEvent="ToggleButton.Checked" SourceName="CommentsToggleButton">
             <BeginStoryboard Storyboard="{StaticResource CommentsExpand}"/>
          </EventTrigger>
          <EventTrigger RoutedEvent="ToggleButton.Unchecked" SourceName="CommentsToggleButton">
             <BeginStoryboard Storyboard="{StaticResource CommentsCollapse}"/>
          </EventTrigger>
       </Page.Triggers>
       <Grid DataContext="{Binding Path=CurrentTask.Workflow.Invoice}" x:Name="DetailsGrid">
          <StackPanel Orientation="Horizontal">
             <Canvas Width="428">
                <GroupBox Width="422" Margin="5,0,0,0">
                   <GroupBox.Header>
                      <StackPanel Orientation="Horizontal">
                         <ToggleButton
                            x:Name="CommentsToggleButton"
                            Width="20"
                            Height="10"
                            Margin="5,0,0,0">
                            <ToggleButton.Content>
                               <Rectangle
                                  Width="5"
                                  Height="5"
                                  Fill="Red"/>
                            </ToggleButton.Content>
                         </ToggleButton>
                         <TextBlock Foreground="Blue" Text="Comments"/>
                      </StackPanel>
                   </GroupBox.Header>
                   <ListView
                      x:Name="CommentsListView"
                      Height="75"
                      ItemsSource="{Binding Path=Comments}">
                      <ListView.View>
                         <GridView>
                            <GridViewColumn DisplayMemberBinding="{Binding Path=Date}" Header="Date"/>
                            <GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="User"/>
                            <GridViewColumn DisplayMemberBinding="{Binding Path=Description}" Header="Comment"/>
                         </GridView>
                      </ListView.View>
                   </ListView>
                </GroupBox>
             </Canvas>
          </StackPanel>
       </Grid>
    </Page>
    
    3 回复  |  直到 16 年前
        1
  •  5
  •   Dabblernl    16 年前

    我也发现这在XAML中是不可能的。您需要DataContextChanged事件,它不是RoutedEvent,因此不能在EventTrigger中使用。

    但这似乎有效:

    <Window x:Class="DatacontextChangedSpike.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <Window.Resources>
            <Storyboard x:Key="ListViewExpands" AutoReverse="True" RepeatBehavior="2x">
                <DoubleAnimation Storyboard.TargetName="PulsingListView" Storyboard.TargetProperty="Height"
                                From="10" To="60"/>
            </Storyboard>
        </Window.Resources>
        <StackPanel>
            <ListView Name="PulsingListView" BorderThickness="2" BorderBrush="Black"
                      DataContextChanged="PulsingListView_DataContextChanged">
                <TextBlock>Listview</TextBlock>
            </ListView>
            <Button Click="Button_Click" >Change DataContext</Button>
        </StackPanel>
    </Window>
    
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Media.Animation;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace DatacontextChangedSpike
    {
        public partial class Window1 : Window
        {
            public Window1()
            {
                DataContext = new List<string>();
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                DataContext = new List<int>();
            }
    
            private void PulsingListView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
            {
                var sb = (Storyboard)FindResource("ListViewExpands");
                sb.Begin();
            }
        }
    }
    
        2
  •  1
  •   Jobi Joy    16 年前

    如果可以在更改DataContext时将ViewModel属性设置为true或false,则可以从DataTrigger(EnterAction和Exitaction)触发故事板。因此,dataTrigger将基于新的bool属性。

        3
  •  0
  •   Ana Betts    16 年前

    我认为您不能通过纯XAML来实现这一点,您必须在代码中实现这一点(或者更好的方法是,编写一个通用表达式行为,以便 可以 用XAML描述)。请检查依赖项属性的PropertyMetadata,以了解如何挂钩其Property Changed事件。