2011-05-06 4 views
7

이러한 애니메이션을 사용하여 ListBox (ListView)를 기반으로 사용자 정의 컨트롤을 만들려고합니다. 목록 상자의 항목이 한 번에 모두로드되지 않고 단계별로 (항목별로, 첫 번째, 두 번째, 세 번째 등).ListBox 항목로드 애니메이션

어떻게하면됩니까?

답변

10

이의 혼합 SDK 동작 사용할 수 있습니다.

<ListBox ItemsSource="{Binding Collection, Source={StaticResource SampleData}}"> 
    <i:Interaction.Behaviors> 
     <b:FadeAnimateItemsBehavior Tick="0:0:0.05"> 
      <b:FadeAnimateItemsBehavior.Animation> 
       <DoubleAnimation From="0" To="1" Duration="0:0:0.3"/> 
      </b:FadeAnimateItemsBehavior.Animation> 
     </b:FadeAnimateItemsBehavior> 
    </i:Interaction.Behaviors> 
</ListBox> 
class FadeAnimateItemsBehavior : Behavior<ListBox> 
{ 
    public DoubleAnimation Animation { get; set; } 
    public TimeSpan Tick { get; set; } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.Loaded += new System.Windows.RoutedEventHandler(AssociatedObject_Loaded); 
    } 

    void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e) 
    { 
     IEnumerable<ListBoxItem> items; 
     if (AssociatedObject.ItemsSource == null) 
     { 
      items = AssociatedObject.Items.Cast<ListBoxItem>(); 
     } 
     else 
     { 
      var itemsSource = AssociatedObject.ItemsSource; 
      if (itemsSource is INotifyCollectionChanged) 
      { 
       var collection = itemsSource as INotifyCollectionChanged; 
       collection.CollectionChanged += (s, cce) => 
        { 
         if (cce.Action == NotifyCollectionChangedAction.Add) 
         { 
          var itemContainer = AssociatedObject.ItemContainerGenerator.ContainerFromItem(cce.NewItems[0]) as ListBoxItem; 
          itemContainer.BeginAnimation(ListBoxItem.OpacityProperty, Animation); 
         } 
        }; 

      } 
      ListBoxItem[] itemsSub = new ListBoxItem[AssociatedObject.Items.Count]; 
      for (int i = 0; i < itemsSub.Length; i++) 
      { 
       itemsSub[i] = AssociatedObject.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; 
      } 
      items = itemsSub; 
     } 
     foreach (var item in items) 
     { 
      item.Opacity = 0; 
     } 
     var enumerator = items.GetEnumerator(); 
     if (enumerator.MoveNext()) 
     { 
      DispatcherTimer timer = new DispatcherTimer() { Interval = Tick }; 
      timer.Tick += (s, timerE) => 
      { 
       var item = enumerator.Current; 
       item.BeginAnimation(ListBoxItem.OpacityProperty, Animation); 
       if (!enumerator.MoveNext()) 
       { 
        timer.Stop(); 
       } 
      }; 
      timer.Start(); 
     } 
    } 
} 

Tick이 항목에 퇴색하기 시작 될 때까지의 시간을 지정을 Animation는 페이드의 불투명도에 적용되는 애니메이션입니다 Xaml에서 매우 비용 효율적으로 설정할 수 있습니다 (예 : 완화 기능 및 페이드 시간).

편집 :.주의이 같은

(를 사용하여 코드 조각 (ItemsSource를 사용하고 INotifyCollectionChanged를 구현하는 경우에만 작동)에서 모든 경우는,이 코드는 데모 용으로 주로 새로운 항목 페이드 인 추가 어떻게 접근 할 수 있는지에 대한 일반적인 아이디어를 얻을 수 있습니다. Blend 4의 네이티브 FluidMoveBehaviors ()

+0

감사합니다. 마지막으로 불투명도 속성없이 Visibility 속성을 사용하여 항목에 애니메이션을 적용하는 방법은 무엇입니까? 나는 그렇게 많이 시도했지만 그것을 할 수는 없다. – JaneKate

+0

['ObjectAnimationUsingKeyFrames'] (http://msdn.microsoft.com/en-us/library/system.windows.media.animation.objectanimationusingkeyframes%28v=vs.95%29.aspx)를 사용하여 가시성을 활성화 할 수 있습니다. [이 답변] (http://stackoverflow.com/questions/5587374/animating-wpf-datagrid-row-details/5588022#5588022)에서 예제를 볼 수 있습니다. –

+0

감사! 그런 애니메이션 (또는 행동)이 특별한 이름 (아코디언? - 최고일지도 모른다!)이 없기 때문에 대답을 찾기 위해 너무 노력했다. – JaneKate