自訂的集合控制設計由 DataTemplate 管理。 資料範本定義每個項目的排版與樣式,並將這些標記套用到集合中的每個項目。 本文說明如何使用 DataTemplateSelector 對集合套用不同的資料範本,並根據你選擇的特定項目屬性或值選擇要使用的資料範本。
重要 API: DataTemplateSelector、 DataTemplate
DataTemplateSelector 是一個能啟用自訂模板選擇邏輯的類別。 它讓你可以定義規則,指定集合中某些項目要使用哪個資料範本。 要實作這個邏輯,你可以在程式碼背後建立 DataTemplateSelector 的子類別,並定義判斷哪個資料範本用於哪個類別的項目(例如某類型項目或具有特定屬性值的項目等)的邏輯。 你可以在 XAML 檔案的資源區段宣告這個類別的實例,並附上你將使用的資料範本定義。 你用一個值來識別這些資源 x:Key ,這樣你就能在 XAML 中參考它們。
先決條件
何時不該使用 DataTemplateSelector
一般來說,你不應該讓 ListView 或 GridView 中的每個項目都採用完全不同的版面或風格——這會不善用 DataTemplateSelector,並負面影響效能。
清單項目視覺顯示的某些元素,可以透過綁定特定屬性,僅用一個資料範本來控制。 例如,每個項目都可以透過在資料範本中綁定至圖示來源屬性的方式,並為該屬性指定不同的值,來擁有不同的圖示。 這樣會比使用 DataTemplateSelector 獲得更好的效能。
何時使用 DataTemplateSelector
當你想在同一個集合控制中使用多個資料範本時,應該建立 DataTemplateSelector 。 A DataTemplateSelector 讓你有彈性讓某些物品突出,同時保持物品的排列相似。 DataTemplateSelector 在許多使用情境中都很有幫助,也有些情況下,建議重新思考你所使用的控制與策略。
收藏控制通常綁定在同一類型的物品集合上。 然而,即使物品可能屬於同一類型,它們在某些屬性上可能有不同的價值,或代表不同的意義。 某些項目可能比其他項目更重要,或某項物品特別重要或不同,需要在視覺上突出。在這種情況下,DataTemplateSelector 會非常有幫助。
你也可以綁定到包含不同類型項目的集合——綁定集合可以包含字串、整數、自訂類別物件等混合。 這使得 DataTemplateSelector 特別實用,因為它能根據項目的物件類型指派不同的資料範本。
以下是一些你可能會使用資料範本選擇器的範例:
- 在 ListView 中代表不同層級的員工——每種員工類型或層級可能需要不同的背景顏色,以便易於區分。
- 在使用 GridView 的產品圖庫中呈現特價商品——特賣商品可能需要紅色背景,或不同顏色的字體,以使其在一般價格商品中脫穎而出。
- 使用 FlipView 在相簿中展示得獎者/熱門照片。
- 需要在 ListView 中用不同的方式表示負數或正數,或是短字串/長字串。
建立一個 DataTemplateSelector
當你建立資料範本選擇器時,你要在程式碼中定義範本選擇邏輯,並在 XAML 中定義資料範本。
程式碼後端元件
要使用資料範本選擇器,首先在程式碼背後建立一個 DataTemplateSelector 的子類別(由它衍生的類別)。 在你的類別中,你宣告每個範本作為該類別的屬性。 接著,你覆寫 SelectTemplateCore 方法,加入你自己的模板選擇邏輯。
以下是一個簡單子類的範例 DataTemplateSelector ,稱為 MyDataTemplateSelector。
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate Normal { get; set; }
public DataTemplate Accent { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
if ((int)item % 2 == 0)
{
return Normal;
}
else
{
return Accent;
}
}
}
該 MyDataTemplateSelector 類別源自類別 DataTemplateSelector ,首先定義兩個 DataTemplate 物件: Normal 與 Accent。 目前這些都是空宣告,但會在 XAML 檔案中用標記「填充」。
此 SelectTemplateCore 方法會接收一個項目物件(即每個集合項目),並藉由設定不同情況下回傳哪個 DataTemplate 的規則來進行覆寫。 在這種情況下,若項目為奇數,則接收 Accent 資料範本;若為偶數,則接收 Normal 資料範本。
XAML 元件
第二,你必須在 XAML 檔案的資源區建立這個新 MyDataTemplateSelector 類別的實例。 所有資源都需要一個標識符 x:Key,你可以用它在稍後的步驟中綁定到集合控制的屬性 ItemTemplateSelector。 你也會建立兩個物件實例 DataTemplate ,並在資源區塊定義它們的配置。 你將這些資料範本指派到你在Accent類別中宣告的Normal和MyDataTemplateSelector屬性。
以下是所需的 XAML 資源與標記範例:
<Page.Resources>
<DataTemplate x:Key="NormalItemTemplate" x:DataType="x:Int32">
<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemChromeLowColor}">
<TextBlock Text="{x:Bind}" />
</Button>
</DataTemplate>
<DataTemplate x:Key="AccentItemTemplate" x:DataType="x:Int32">
<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemAccentColor}">
<TextBlock Text="{x:Bind}" />
</Button>
</DataTemplate>
<l:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
Normal="{StaticResource NormalItemTemplate}"
Accent="{StaticResource AccentItemTemplate}"/>
</Page.Resources>
如上所示,資料範本Normal和Accent定義為將項目顯示為按鈕。然而,Accent資料範本將使用強調色筆刷作為背景,而Normal資料範本則使用灰色筆刷(SystemChromeLowColor)。 這兩個資料範本接著被指派到 Normal 和 Accent DataTemplate 物件,這些物件是 MyDataTemplateSelector 類別的屬性,這些物件是在 C# 程式碼背後建立的。
最後一步是將 DataTemplateSelector 綁定到收藏控制項的 ItemTemplateSelector 屬性(此例中是 ListView)。 這取代了對房產賦予價值 ItemTemplate 的需求。
<ListView x:Name = "TestListView"
ItemsSource = "{x:Bind NumbersList}"
ItemTemplateSelector = "{StaticResource MyDataTemplateSelector}">
</ListView>
當你的程式碼編譯完成後,每個集合項目將會在SelectTemplateCore中透過覆寫的MyDataTemplateSelector方法執行,並用適當的 DataTemplate 來渲染。
這很重要
使用 DataTemplateSelector 搭配 ItemsRepeater 時,你需要將 DataTemplateSelector 綁定到 ItemTemplate 屬性。
ItemsRepeater 沒有屬性 ItemTemplateSelector 。
DataTemplateSelector 效能考量
當你使用 ListView 或 GridView 處理大量資料時,捲動和橫移的效能可能會成為一個問題。 為了讓大型收藏持續良好運作,你可以採取一些步驟來提升資料範本的效能。 這些功能在 ListView 和 GridView UI 優化中有更詳細的說明。
- 每項元素減少 ——將資料範本中的 UI 元素數量控制在合理最低。
- 異質集合的容器回收
- 使用 ChoosingItemContainer 事件 - 此事件是一種高效能的方法,用於為不同項目應用不同的資料模板。 為了達到最佳效能,你應該優化快取並選擇針對特定資料的資料範本。
- 使用 項目模板選擇器 - 在某些情況下應避免使用項目模板選擇器(
DataTemplateSelector),因為會影響效能。