資料範本選擇:根據其屬性進行項目設計

自訂的集合控制設計由 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),因為會影響效能。