Как анимировать ContentControl в ItemsControl - PullRequest
1 голос
/ 25 февраля 2012

Мне нравится использовать ItemsControl для размещения ContentsControls. Каждый новый ContentsControl анимирует свое содержимое, когда элемент добавляется и каждый ContentControl и перекрывает предыдущий. Элементы ItemsControl и ContentControl связаны с Caliburn Micro с использованием соглашений об именах.

                    <ItemsControl x:Name="OverlayStackedItems" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Grid x:Name="ItemsHost" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>

                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <cc:DummyContentControl cal:View.Model="{Binding}" />
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>

ContentControl определяется следующим образом:

   [ContentProperty("Content")]
public partial class DummyContentControl :ContentControl
{
    public DummyContentControl()
    {
    }

    static DummyContentControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(DummyContentControl), new FrameworkPropertyMetadata(typeof(ContentControl)));
    }


    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
    }

    protected override void OnContentChanged(object oldContent, object newContent)
    {
        LayoutUpdated += (sender, e) => 
        { 
        };
        UpdateLayout();

        base.OnContentChanged(oldContent, newContent);
    }

    void DummyContentControl_LayoutUpdated(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }

    protected override Size MeasureOverride(Size constraint)
    {
        return base.MeasureOverride(constraint);
    }
}

Итак, наконец, мой вопрос. В реальном ContentControl я люблю анимировать контент, но ContentControl имеет размер 0, когда вызывается OnContentChange, где создается моя анимация. Порядок вызовов при размещении ContentControl в ItemsControl:

  1. OnContentChanged (Ошибка анимации)
  2. OnApplyTemplate
  3. MeasureOverride

Когда ContentControl запускается сам по себе, порядок:

  1. OnApplyTemplate
  2. MeasureOverride
  3. OnContentChanged (Анимация работает)

Проблема здесь в том, что полное визуальное поддерево нового Item в ItemsControl равно 0 (DesiredSize, ActualSize = 0), поэтому мой код анимации завершается ошибкой. Я надеюсь, что это имеет смысл для кого-то, Любая помощь будет великолепна, Thx, J

------------------------------ Редакция ---------------- ---

Хорошо, я добавил обработчик событий OnLoaded в ctor DummyControl. Порядок звонков 1. OnContentChanged (все размеры 0) 2. OnApplyTemplate (все размеры 0) 3. MeasureOverride (вызывается несколько раз, вероятно, для всех дочерних элементов управления, размещаемых ContentControl) 4. Загруженное событие (установлен желаемый размер, все остальные размеры по-прежнему равны 0)

Может ли кто-нибудь объяснить, каков рекомендуемый метод анимации ContentControl? Хостет с помощью ItemsControl?

1 Ответ

0 голосов
/ 29 марта 2012

Просто сделайте все в XAML и дайте анимации сделать свое дело, не вызывая MeasureOverride () и остальные хуки.

<ItemsControl>
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Border>
                            <TextBlock Text="Whatever your template should look like"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                                <BeginStoryboard>
                                    <Storyboard >
                                        <DoubleAnimation Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleX)" Duration="0:0:0.5" From="0" To="1" />
                                        <DoubleAnimation Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleY)" Duration="0:0:0.5" From="0" To="1" />
                                        <DoubleAnimation Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.CenterX)" Duration="0:0:0.5" To="25" />
                                        <DoubleAnimation Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.CenterY)" Duration="0:0:0.5" To="25" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>
...