起動時には最新のつぶやきが一番上に来るのに、
次のタイマ時刻のつぶやきからは下に追加されていきます。
というわけで今回はソート機能を追加します。
まず、時間を取得します。
私が知らないだけかもしれませんが、
JSONから直接DateTime型で取得できないみたいなので、
いったんstringで受け取ってから変換します。
[DataMember(Name = "created_at")] private string CreatedAtString { get; set; } private DateTime? _createdAt = null; public DateTime CreatedAt { get { if (_createdAt == null) { _createdAt = DateTime.ParseExact(CreatedAtString, "ddd MMM dd HH:mm:ss zzzz yyyy", CultureInfo.GetCultureInfoByIetfLanguageTag("en-us")); } return _createdAt.Value; } }
CreatedAtの方にはDataMember属性がついていないことに注意してください。
このためJSON形式としては読み込まれず(=nullのまま)、
初めてgetが呼び出されたときにParseExactで文字列からDateTime型に変換します。
このCreatedAtはViewModelにも追加しています。
次にViewを変更します。
複雑になりそうなので、タイムライン部分をTimelineViewクラスに切り出しました。
よってMainWindowは以下のように簡単になります。
<Window x:Class="WTwitter.View.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vmt="clr-namespace:WTwitter.ViewModel.Twitter" xmlns:vw="clr-namespace:WTwitter.View" xmlns:CompModel="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="WTwitter" Height="500" Width="400"> <Window.Resources> <DataTemplate DataType="{x:Type vmt:TimelineViewModel}"> <vw:TimelineView/> </DataTemplate> </Window.Resources> <TabControl ItemsSource="{Binding Path=Timelines}"> <TabControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=DisplayName}"/> </DataTemplate> </TabControl.ItemTemplate> </TabControl> </Window>
見ての通り、TabControlのContentTemplateがなくなりました。
そのかわりWindow.ResourceにDataTemplateを追加しています。
これは、TimelineViewModel型の表示を要求されたら、
TimelineViewを使うということです。
TabControlには依然としてItemsSourceとしてTimelinesを指定しているので、
Timelineを表示しようとして、そのときにDataTemplateがあるのでそっちを見に行くという仕組みです。
ではTimelineViewを見てみます。
<UserControl x:Class="WTwitter.View.TimelineView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:compModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"> <UserControl.Resources> <CollectionViewSource x:Key="AllItemsViewSource" Source="{Binding Path=AllItems}"> <CollectionViewSource.SortDescriptions> <compModel:SortDescription PropertyName="CreatedAt" Direction="Descending"/> </CollectionViewSource.SortDescriptions> </CollectionViewSource> </UserControl.Resources> <ListBox ItemsSource="{Binding Source={StaticResource AllItemsViewSource}}" 以下略
ResourceとしてCollectionViewSourceを追加していて、
(=CollectionViewSourceのインスタンスを生成して、UserControlのリソースとして追加)
ListBoxのItemsSourceにそれを指定しています。
ListBoxに直接Sort方法をしていする方法はないみたいで、
CollectionViewSourceを通じて指定しています。
CollectionViewSourceは私もよく説明できないのですが、
Collectionを表示するようなViewを操作する一般的な方法を集めた
あらかじめ用意されたViewModelのようなもので、
どのようなViewにするかに依存しないでリストを操作できます。
今回のソースコード
http://wtwitter.codeplex.com/SourceControl/changeset/view/39354
0 件のコメント:
コメントを投稿