UWP 使用 CharacterGroupings 達成 LongListSelector 的內容分組

UWP LongListSelector 在 ZoomedOutView 所需要的分組 Key 該怎麼簡單的分類呢?

之前的文章 UWP 的 LongListSelector 在做 ZoomedOutView 的畫面時,

用的是所有資料的第一個字當作分類的 Key,

這或許在英文語系上還可行,但是遇到中文字就不適用了,

這篇我們來介紹如何做多語系的分類。

專案內容就接續 UWP 的 LongListSelector 的專案,讓我們繼續改進他。

在 DataManager 類別裡,我們增加一些中文的模擬資料,

造之前取第一個字當作分類的 Key 的作法會如下圖

中文也是取第一個字來分類,這看起來不太妙!

所以分類方式就要改變了,

先在 Models 目錄下增加一個類別 AlphaKeyContent,程式碼如下

public class AlphaKeyContent : ObservableCollection<AccountItem>{
    public string Key { get; set; }
}

這是用來放我們分類資料的類別。

再來將 DataManager 的建構式改寫成下面程式碼

public DataManager() {
    AlphaGroups = new ObservableCollection<AlphaKeyContent>();
    CharacterGroupings cg = new CharacterGroupings();
    
    foreach (var key in cg) {
        if (!string.IsNullOrEmpty(key.Label)) {
            AlphaGroups.Add(new AlphaKeyContent { Key = key.Label });
        }
    }
    var list = from f in DataList
               group f by cg.Lookup(f.Name) into g
               orderby g.Key
               select g;
    foreach (var group in list) {
        var collection = AlphaGroups.FirstOrDefault(f => group.Key.Equals(f.Key));
        if (collection == null) collection = AlphaGroups.Last();
        foreach (var item in group) {
            collection.Add(item);
        }
    }
}

這裡的重點就是 CharacterGroupings 這個類別了,

首先 CharacterGroupings 本身就是一個集合,內容是 CharacterGrouping ,在此系統下的文字分類。

因為我們想把所有分類都顯示出來,所以會用 foreach 將 AlphaKeyContent 先建立起來。

再來就使用 CharacterGroupings .Lookup,他會回傳參數給的字其所在的分類。

但是執行結果會如下

沒有資料的 Group 也被顯示出來了,所以在 Xaml 的 GroupStyle 要特別設定一個屬性 HidesIfEmpty = "true"

<GroupStyle HeaderTemplate="{StaticResource GroupHeaderDataTemplate}" HidesIfEmpty="True"/>

接著為了美觀,我們也把 ZoomedOutView 的 ListView 改成 GridView。

並將 ZoomOutHeaderDataTemplate 改成適合 GridView 內容的樣式,

再運用 UWP 的 DataTriggerBehavior 這篇介紹的 DataTriggerBehavior 來讓沒有資料的 Group 變色就大功告成囉!

 最後完成的 DataTemplate 如下

<DataTemplate x:Key="ZoomOutHeaderDataTemplate">
    <Grid Height="100" Width="100">
        <TextBlock Text="{Binding Group.Key}" Style="{StaticResource HeaderTextBlockStyle}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{ThemeResource SystemControlBackgroundAccentBrush}">
        <Interactivity:Interaction.Behaviors>
        	<Core:DataTriggerBehavior Binding="{Binding Group.Count, Mode=OneWay}" Value="0">
        		<Core:ChangePropertyAction PropertyName="Foreground">
        			<Core:ChangePropertyAction.Value>
        				<SolidColorBrush Color="#FFB4B4B4"/>
        			</Core:ChangePropertyAction.Value>
        		</Core:ChangePropertyAction>
        	</Core:DataTriggerBehavior>
        </Interactivity:Interaction.Behaviors>
        </TextBlock>
    </Grid>
</DataTemplate>

執行結果如下

範例下載