2012-12-31 47 views
4

最近我開始構建我自己的大型Windows 8商店應用程序。 在UI上工作我開始複製一些好的用戶界面。ListView的項目在WinRT中插入動畫

其中一個我遇到了在標準郵件應用程序的列表視圖中插入新元素的非常有趣的動畫。當你點擊鏈條時,它會展開並顯示鏈條中的所有消息。

Here是捕獲的視頻。

我不知道他們用什麼技術來實現這個動畫和行爲。

任何人都可以幫助我,解釋或舉例如何實現這樣的行爲?謝謝。

回答

18

郵件應用程序是用JavaScript編寫的,所以它不會幫助您瞭解它是如何完成的,因爲此UI堆棧與XAML完全不同。儘管如此,列表控件可能採用相同的動畫方式,所以您只需添加/刪除列表中的某些項目即可獲得展開/摺疊效果。

我玩了一下,這就是我使用ListView的ItemTemplateSelector屬性來定義幾個不同的項目模板。

enter image description here

<Page 
    x:Class="App82.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:App82" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 
    <Page.Resources> 
     <local:CollapsibleListItemTemplateSelector 
      x:Key="collapsibleListItemTemplateSelector"> 
      <local:CollapsibleListItemTemplateSelector.BasicItemTemplate> 
       <DataTemplate> 
        <Border 
         Margin="5" 
         Height="50" 
         VerticalAlignment="Stretch" 
         BorderBrush="ForestGreen" 
         BorderThickness="2,0,0,0"> 
         <StackPanel 
          Margin="10,0,0,0"> 
          <TextBlock 
           FontWeight="Bold" 
           Text="{Binding Title}" /> 
          <TextBlock 
           Text="{Binding Gist}" /> 
         </StackPanel> 
        </Border> 
       </DataTemplate> 
      </local:CollapsibleListItemTemplateSelector.BasicItemTemplate> 
      <local:CollapsibleListItemTemplateSelector.ExpandedItemTemplate> 
       <DataTemplate> 
        <Border 
         Margin="15,5,5,5" 
         Height="50" 
         VerticalAlignment="Stretch" 
         BorderBrush="Yellow" 
         BorderThickness="2,0,0,0"> 
         <StackPanel 
          Margin="10,0,0,0"> 
          <TextBlock 
           FontWeight="Bold" 
           Text="{Binding Title}" /> 
          <TextBlock 
           Text="{Binding Gist}" /> 
         </StackPanel> 
        </Border> 
       </DataTemplate> 
      </local:CollapsibleListItemTemplateSelector.ExpandedItemTemplate> 
      <local:CollapsibleListItemTemplateSelector.CollapsibleItemTemplate> 
       <DataTemplate> 
        <Border 
         Margin="5" 
         Height="50" 
         VerticalAlignment="Stretch" 
         BorderBrush="DodgerBlue" 
         BorderThickness="2,0,0,0"> 
         <StackPanel 
          Margin="10,0,0,0" 
          Orientation="Horizontal"> 
          <TextBlock 
           FontWeight="Bold" 
           Text="{Binding ChildItems.Count}" /> 
          <TextBlock 
           FontWeight="Bold" 
           Text="&#160;Items" /> 
         </StackPanel> 
        </Border> 
       </DataTemplate> 
      </local:CollapsibleListItemTemplateSelector.CollapsibleItemTemplate> 
     </local:CollapsibleListItemTemplateSelector> 
    </Page.Resources> 
    <Grid 
     Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> 
     <ListView 
      x:Name="ListView" 
      ItemTemplateSelector="{StaticResource collapsibleListItemTemplateSelector}" 
      ItemClick="OnItemClick" 
      IsItemClickEnabled="True" /> 
    </Grid> 
</Page> 

後面的代碼:

using System.Collections; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using App82.Common; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 

namespace App82 
{ 
    public sealed partial class MainPage : Page 
    { 
     public MainPage() 
     { 
      this.InitializeComponent(); 

      var items = new ObservableCollection<BindableBase>(); 
      var item1 = new BasicItem { Title = "Item 1", Gist = "This item has some content that is not fully shown..." }; 
      var item2 = new ExpandedItem { Title = "Item 2", Gist = "This item has some content that is not fully shown..." }; 
      var item3 = new ExpandedItem { Title = "Item 3", Gist = "This item has some content that is not fully shown..." }; 
      var item4 = new ExpandedItem { Title = "Item 4", Gist = "This item has some content that is not fully shown..." }; 
      var item5 = new BasicItem { Title = "Item 5", Gist = "This item has some content that is not fully shown..." }; 

      var itemGroup1 = new CollapsibleItem(items, new[] { item2, item3, item4 }); 
      items.Add(item1); 
      items.Add(itemGroup1); 
      items.Add(item5); 
      this.ListView.ItemsSource = items; 
     } 

     private void OnItemClick(object sender, ItemClickEventArgs e) 
     { 
      var collapsibleItem = e.ClickedItem as CollapsibleItem; 
      if (collapsibleItem != null) 
       collapsibleItem.ToggleCollapse(); 
     } 
    } 

    public class CollapsibleListItemTemplateSelector : DataTemplateSelector 
    { 
     public DataTemplate BasicItemTemplate { get; set; } 
     public DataTemplate CollapsibleItemTemplate { get; set; } 
     public DataTemplate ExpandedItemTemplate { get; set; } 

     protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container) 
     { 
      if (item is ExpandedItem) 
       return ExpandedItemTemplate; 
      if (item is BasicItem) 
       return BasicItemTemplate; 
      //if (item is CollapsibleItem) 
       return CollapsibleItemTemplate; 
     } 
    } 

    public class BasicItem : BindableBase 
    { 
     #region Title 
     private string _title; 
     public string Title 
     { 
      get { return _title; } 
      set { this.SetProperty(ref _title, value); } 
     } 
     #endregion 

     #region Gist 
     private string _gist; 
     public string Gist 
     { 
      get { return _gist; } 
      set { this.SetProperty(ref _gist, value); } 
     } 
     #endregion 
    } 

    public class ExpandedItem : BasicItem 
    { 

    } 

    public class CollapsibleItem : BindableBase 
    { 
     private readonly IList _hostCollection; 

     #region IsExpanded 
     private bool _isExpanded; 
     public bool IsExpanded 
     { 
      get { return _isExpanded; } 
      set 
      { 
       if (this.SetProperty(ref _isExpanded, value)) 
       { 
        if (_isExpanded) 
         Expand(); 
        else 
         Collapse(); 
       } 
      } 
     } 
     #endregion 

     #region ChildItems 
     private ObservableCollection<BasicItem> _childItems; 
     public ObservableCollection<BasicItem> ChildItems 
     { 
      get { return _childItems; } 
      set { this.SetProperty(ref _childItems, value); } 
     } 
     #endregion 

     public CollapsibleItem(
      IList hostCollection, 
      IEnumerable<BasicItem> childItems) 
     { 
      _hostCollection = hostCollection; 
      _childItems = new ObservableCollection<BasicItem>(childItems); 
     } 

     public void ToggleCollapse() 
     { 
      IsExpanded = !IsExpanded; 
     } 

     private void Expand() 
     { 
      int i = _hostCollection.IndexOf(this) + 1; 

      foreach (var childItem in ChildItems) 
      { 
       _hostCollection.Insert(i++, childItem); 
      } 
     } 

     private void Collapse() 
     { 
      int i = _hostCollection.IndexOf(this) + 1; 

      for (int index = 0; index < ChildItems.Count; index++) 
      { 
       _hostCollection.RemoveAt(i); 
      } 
     } 
    } 
} 
+0

謝謝你這麼大的答案! – imslavko