Как анимировать панель Templated Parent.ZIndex в WPF? - PullRequest
1 голос
/ 12 июля 2011

Я пытаюсь перенести шаблонный элемент вперед (ZIndex) в стековую панель с привязкой к данным.Поскольку панель стека создает ContentPresenter для каждого элемента в нем, мое визуальное дерево выглядит следующим образом:

ItemsControl
  Border
    ItemsPresenter
      StackPanel
        ContentPresenter
          ToggleButton
        ContentPresenter
          ToggleButton
        ContentPresenter
          ToggleButton

При нажатии кнопки ToggleButton она запускает раскадровку следующим образом:

<Storyboard x:Key="MyStoryboard" >
    <Int32AnimationUsingKeyFrames BeginTime="0:0:0.000" Duration="0:0:0.350" 
          Storyboard.TargetProperty="TemplatedParent.(Panel.ZIndex)" >
        <Int32KeyFrameCollection>
            <DiscreteInt32KeyFrame KeyTime="0:0:0.000" Value="99" />
        </Int32KeyFrameCollection>
    </Int32AnimationUsingKeyFrames>
</Storyboard>       



<Style x:Key="SubStateOptionButtonStyle" TargetType="ToggleButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">

                <!-- Toggle Button Contents here -->

                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="Button.Click">
                        <EventTrigger.Actions>
                            <BeginStoryboard Storyboard="{StaticResource MyStoryboard}" />
                        </EventTrigger.Actions>
                    </EventTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Однако TemplatedParent. (Panel.ZIndex) дает мне странное исключение:

Значение не может быть нулевым.Имя параметра: dp

в System.Windows.DependencyObject.GetValue (DependencyProperty dp) в System.Windows.Media.Animation.Storyboard.ProcessComplexPath (HybridDictionary clockMappings, DependencyObject targetObject, анимация пути пути, свойство-путь-путь-обхода, блокировка по пути к себе, блокировка по пути объекта, блокировка объекта, анимация объекта)Слой Int64) в System.Windows.Media.Animation.Storyboard.ClockTreeWalkRecursive (Clock currentClock, DependencyObject, содержащийObject, INameScope nameScope, DependencyObject parentObject, String parentObjectName, PropertyPath parentPropertyPath, HandoffBehaictionaryMackingMapDefenderMeditionMunctionWid.Animation.Storyboard.ClockTreeWalkRecursive (Clock currentClock, DependencyObject, содержащийObject, INameScope nameScope, DependencyObject parentObject, String parentObjectName, PropertyPath parentPropertyPath, HandoffBehavior handoffBehavior.mocketMeditionSystemWindows.Info.Control.Amp32.Amp32.Amp32.Chint.Windows.Mision.Amp32.AmpMate.SystemMed.SystemBectionSecate.SystemBeginS.SystemBeginS.ShellMed.Wision.Sec .Med.Sec .Med.SystemMed.Wision.Sec .Med.SystemMed.Sec .Med.Sec... .MBe .Sec.......... Понадобится...n (DependencyObject, содержащийObject, INameScope nameScope, HandoffBehavior handoffBehavior, Boolean isControllable, слой Int64) в System.Windows.Media.Animation.BeginStoryboard.Begin (DependencyObject targetObject, IName

1011

1012 *1013* * * 1022) *

Я дважды проверил через code-behind, что TemplatedParent элемента ToggleButton действительно является ContentPresenter, и я могу установить ZIndex примерно так:

Panel.SetZIndex((sender as ToggleButton).TemplatedParent as UIElement, 99);

Но я бы хотел оживить его с помощьюРаскадровка, желательно с прямым XAML, поскольку она должна оставаться впереди на протяжении всей раскадровки, а затем вернуться туда, где она была.

Я рассмотрел наследование от ItemsControl, чтобы предотвратить создание ContentPresenter, но этожесткое решение чего-то, что кажется легким.

1 Ответ

0 голосов
/ 02 мая 2012

Вот ответ на этот вопрос: http://social.msdn.microsoft.com/Forums/en/wpf/thread/7b9b8209-063d-46b2-a03f-98b393cf9514 (Мин Чжу [MSFT])

Ваш исходный код не работает, потому что TemplatedParent не является свойством зависимости. Так что это не правильный путь для анимации.

Код, предложенный TI82, верен. Это все еще не работает, потому что TemplatedParent - Кнопка. Но элемент, который вы хотите анимировать - это контейнер элемента.

Чтобы анимировать контейнер элемента, вы можете использовать ItemControl ItemContainerStyle. Button.Click - это событие с маршрутизацией пузырьков, поэтому оно будет перемещаться и от кнопки к контейнеру элемента.

Попробуйте следующий код.

<Window.Resources>
    <Storyboard x:Key="MyStoryboard">
      <ColorAnimation Storyboard.TargetName="ButtonRect" 
                            Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" 
                            To="Red" 
                            Duration="0:0:0.350"
                            FillBehavior="Stop"/>
    </Storyboard>

    <Style x:Key="MyButtonStyle" TargetType="Button">
      <Setter Property="Panel.ZIndex" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentPresenter}, Mode=OneWayToSource, Path=(Panel.ZIndex)}"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="Button">
            <Grid Height="60" Margin="0,0,0,-10" >
              <Border BorderBrush="Black" BorderThickness="2" CornerRadius="15">
                <Rectangle x:Name="ButtonRect" RadiusX="15" RadiusY="15" Fill="AliceBlue" />
              </Border>
              <TextBlock Text="{Binding}" FontSize="15" TextAlignment="Center" VerticalAlignment="Center"/>
            </Grid>
            <ControlTemplate.Triggers>
              <EventTrigger RoutedEvent="Button.Click">
                <EventTrigger.Actions>
                  <BeginStoryboard Storyboard="{StaticResource MyStoryboard}" />
                </EventTrigger.Actions>
              </EventTrigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

    <DataTemplate x:Key="MyButtonTemplate">
      <Grid>
        <Button Style="{StaticResource MyButtonStyle}" />
      </Grid>
    </DataTemplate>


    <Storyboard x:Key="MyStoryboard2">
      <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.ZIndex)" 
       BeginTime="0:0:0.000" Duration="0:0:0.350" FillBehavior="Stop">
        <Int32KeyFrameCollection>
          <DiscreteInt32KeyFrame KeyTime="0:0:0.000" Value="99" />
        </Int32KeyFrameCollection>
      </Int32AnimationUsingKeyFrames>
    </Storyboard>

    <Style x:Key="MyItemContainerStyle">
      <Style.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
          <BeginStoryboard Storyboard="{StaticResource MyStoryboard2}"/>
        </EventTrigger>
      </Style.Triggers>
    </Style>
  </Window.Resources>

  <Grid>
    <ItemsControl ItemsSource="ABCDEF" 
           ItemTemplate="{StaticResource MyButtonTemplate}" 
           ItemContainerStyle="{StaticResource MyItemContainerStyle}">
      <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
          <StackPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
    </ItemsControl>
  </Grid>
...