資料繫結和清單

已完成

U W P 和 W P F 的技術標誌。W P F 顯示為暗灰色。

到目前為止,您只使用資料繫結來顯示及編輯單一物件的屬性。 在此課程中,您會套用資料繫結以顯示物件集合。 為了讓事情簡化,這些物件將會是色彩。 更具體來說,它們將會是 ColorDescriptor 類別的多個執行個體。

1.建立 ColorDescriptor 類別

讓我們建立此類別。 在 [方案總管] 中,以滑鼠右鍵按一下 DatabindingSample 專案、選取 [新增 / 類別],然後輸入 ColorDescriptor 作為類別的名稱。 選取 [新增] 以建立類別。

ColorDescriptor 包含兩個屬性:以 Windows.UI.Color 物件表示的色彩本身,以及色彩名稱。 它也有填滿這些屬性的建構函式、顯示色彩名稱的 ToString() 方法,以及代表 R、G、B 色彩元件的十六進位值。 這是整個 ColorDescriptor 類別。

using Windows.UI;

namespace DatabindingSample
{
    public class ColorDescriptor : ObservableObject
    {
        public ColorDescriptor(Color color, string name)
        {
            Color = color;
            Name = name;
        }

        public Color Color { get; private set; }

        public string Name { get; private set; }

        public override string ToString()
        {
            return $"{Name} (#{Color.R:X2}{Color.G:X2}{Color.B:X2})";
        }
    }
}

請以上述程式碼取代 ColorDescriptor.cs 檔案的預設內容。

2.建立 ColorList.xaml 頁面

為了顯示色彩清單,我們將會使用新的 XAML 頁面。 在 [方案總管] 中,以滑鼠右鍵按一下 DatabindingSample,然後選取 [新增] / [新項目]。 從可用項目清單選擇 [空白頁],然後輸入 ColorList 作為名稱。 選取 [新增] 以建立頁面。

顯示 [新增專案] 對話方塊中 [Visual C Sharp] 底下選取 [空白頁面] 的螢幕擷取畫面。

3.設定啟動頁面

如果您現在啟動應用程式,它會開啟並顯示 [MainPage] 頁面。 因為您將使用新建立的 ColorList.xaml 頁面,建議您將它設定為起始頁面。 若要這樣做,請開啟 App.xaml.cs 並尋找瀏覽到 [MainPage] 的程式碼行。

rootFrame.Navigate(typeof(MainPage), e.Arguments);

MainPage 取代為 ColorList,並確認當您啟動應用程式 (按 F5 或選取 [偵錯] / [開始偵錯]) 時,會啟動 [ColorList] 頁面。

4.建立色彩清單的邏輯

我們將繼續使用先前介紹的最佳做法來建立新頁面的獨立式邏輯。 那麼,請繼續並建立名為 ColorListLogic 的新類別。

在 [方案總管] 中,以滑鼠右鍵按一下 DatabindingSample 專案,選取 [新增] / [類別],然後輸入 ColorListLogic 作為類別的名稱。 選取 [新增] 以建立類別,並將下列內容貼到檔案中:

using System.Collections.Generic;
using System.Collections.ObjectModel;

using Windows.UI;

namespace DatabindingSample
{
    public class ColorListLogic : ObservableObject
    {
        public List<ColorDescriptor> LotsOfColors { get; private set; }

        public ColorListLogic()
        {
            LotsOfColors = new List<ColorDescriptor>
            {
               new ColorDescriptor(Colors.Red, "red"),
               new ColorDescriptor(Colors.White, "white"),
               new ColorDescriptor(Colors.Green, "green"),
               new ColorDescriptor(Colors.Yellow, "yellow"),
               new ColorDescriptor(Colors.Blue, "blue"),
               new ColorDescriptor(Colors.Black, "black")
            };

        }
    }
}

ColorListLogic 類別非常簡單 (至少目前如此)。 它有一個稱為 LotsOfColors 的屬性, 這是 ColorDescriptor 物件的 List。 清單中已填入類別建構函式中的一些色彩。 就是這麼容易!

5.在 ListBox 中顯示色彩

下一步是在我們的應用程式中顯示色彩。 首先,讓我們將 ColorListLogic 設定為可從 XAML 存取。 開啟 ColorList.xaml.cs,並將下列內容新增到 ColorList 類別:

public ColorListLogic Logic { get; } = new ColorListLogic();

我們在這裡使用的語法,與先前針對 MainPageLogic 所使用的語法相同。 它會建立僅供取得屬性,並初始化其值至新建立的 ColorListLogic 物件。

接著,開啟 ColorList.xaml 並在 Grid 元素內新增下列 XAML。

<ListBox ItemsSource="{x:Bind Logic.LotsOfColors}" 
         Margin="20" 
         Width="200"
         HorizontalAlignment="Left" 
         VerticalAlignment="Top"/>

這裡有趣的部分是 ItemsSource 屬性。 如名稱所示,它提供 ListBox 中所顯示之項目的來源。 而且它直接繫結到 ColorListLogicLotsOfColors 屬性。

若您現在執行應用程式,它會在 ListBox 中顯示色彩! 但並不太美觀。 ListBox 似乎已叫用儲存在 LotsOfColors 清單中之 ColorDescriptorToString() 方法。

顯示 [資料系結範例] 視窗的螢幕擷取畫面,其中已選取黃色。

6.定義項目的範本

讓範本顯示儲存在 屬性中 ColorDescriptor.Color 的實際色彩,以及其名稱相當好。 就像這樣:

範本的螢幕擷取畫面。

若要在 XAML 中為此撰寫程式碼,我們可以在 StackPanel 中放置已上色的 RectangleTextBlock

<StackPanel Orientation="Horizontal">
    <Rectangle Width="80" Height="20">
        <Rectangle.Fill>
            <SolidColorBrush Color="Blue"/>
        </Rectangle.Fill>
    </Rectangle>
    <TextBlock Text="blue" Margin="20, 10, 0, 10"/>
</StackPanel>

這是 XAML 與資料繫結的其中一個強項。 幾乎所有複雜視覺效果都是以您可以重新定義的範本為基礎。 若要使用上述的 StackPanel 作為範本,我們必須將它放在 DataTemplate 內。 DataTemplate 必須定義 DataType,其為可套用範本的資料類型。 在我們的案例中,它是 ColorDescriptor 類別。 因此,DataTemplate 看起來像這樣:

<DataTemplate x:DataType="local:ColorDescriptor">
    <!-- template content comes here -->
</DataTemplate>

資料在 ListBox (以及許多其他控制項) 中會如何呈現,是由其 ItemTemplate 所控制,這應該設定為 DataTemplate。 有多種方法可以這麼做。 在此課程中,我們會簡單地使用下列語法在 ListBox 內定義 DataTemplate

<ListBox ...>
    <ListBox.ItemsSource>
        <DataTemplate ...>
            ...
        </DataTemplate>
    </ListBox.ItemsSource>
</ListBox>

稍後,您將會看到如何透過將 DataTemplate 定義為資源,來在多個地方重複使用它。

現在,整個 ListBox 看起來像這樣 (若您還沒有跟著這樣做,請使用下列 XAML 取代整個 <ListBox> 標記):

<ListBox ItemsSource="{x:Bind Logic.LotsOfColors}" 
         Margin="20" 
         Width="200"
         HorizontalAlignment="Left" 
         VerticalAlignment="Top">
    <ListBox.ItemTemplate>
        <DataTemplate x:DataType="local:ColorDescriptor">
            <StackPanel Orientation="Horizontal">
                <Rectangle Width="80" 
                           Height="20">
                    <Rectangle.Fill>
                        <SolidColorBrush Color="{x:Bind Color}"/>
                    </Rectangle.Fill>
                </Rectangle>
                <TextBlock Text="{x:Bind Name}" 
                           Margin="20, 10, 0, 10"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

請注意,因為 ListBox 中的每個項目都對應到 ColorDescriptor 物件,您只需要在此類別內容內的範本內定義繫結。 編譯器甚至會檢查 Logic.LotsOfColors 是否包含 ColorDescriptor 物件,以及 ColorDescriptor.ColorColorDescriptor.Name 是否存在且為正確類型。

7.執行應用程式

現在按 F5 或選取功能表中的 [偵錯] > [開始偵錯] 來執行應用程式。 您應該會看到色彩清單。

顯示 [資料系結範例] 視窗的螢幕擷取畫面,其中矩形旁邊的六個色彩清單代表色彩。

如果您以偵錯模式啟動 XAML 應用程式,便可以利用即時 XAML 編輯功能。 您甚至無須停止應用程式或按 [儲存]。 只須變更 XAML,絕大多數的變更就會立即反映在執行中的應用程式上。 試試看吧。 將資料範本內 RectangleWidthHeight 變更為 30,藉此將彩色矩形轉換成正方形。

顯示 [資料系結範例] 視窗的螢幕擷取畫面,其中方塊旁邊有六個色彩的清單,代表色彩。

這稱為XAML 熱重新載入,它對於微調應用程式中的配置和動畫很有用。

摘要

此課程已說明在 ListBox 中顯示多個項目的基本概念。 還有其他相似用途的控制項可供使用,例如 ItemsControlListViewGridView。 但其基本原理都相同:將您的物件清單 (IEnumerableList<>) 繫結至 ItemsSource 屬性,然後定義 DataTemplates 以控制個別清單項目的顯示方式和行為模式。 您也可以重新定義這些項目的配置,甚至是容器控制項本身的外觀 (不過這已超出此課程模組的範圍)。

請注意,程式碼本身一律不須處理 ListBox 本身。 它只須建立商務物件 (ColorDescriptor) 的集合,XAML 執行階段便會負責擴充每個項目的範本。

下個課程會說明如何從 ListBox 或下拉式清單中選取項目,以及從程式碼變更清單內容,以便讓元素的新增和移除反映在 UI 上。

U W P 和 W P F 的技術標誌。U W P P 顯示為暗灰色。

到目前為止,您只使用資料繫結來顯示及編輯單一物件的屬性。 在此課程中,您會套用資料繫結以顯示物件集合。 為了讓事情簡化,這些物件將會是色彩。 更具體來說,它們將會是 ColorDescriptor 類別的多個執行個體。

1.建立 ColorDescriptor 類別

讓我們建立此類別。 在 [方案總管] 中,以滑鼠右鍵按一下 DatabindingSampleWPF 專案、選取 [新增 / 類別],然後輸入 ColorDescriptor 作為類別的名稱。 選取 [新增] 以建立類別。

ColorDescriptor 包含兩個屬性:以 Windows.UI.Color 物件表示的色彩本身,以及色彩名稱。 它也有填滿這些屬性的建構函式、顯示色彩名稱的 ToString() 方法,以及代表 R、G、B 色彩元件的十六進位值。 這是整個 ColorDescriptor 類別。

using System.Windows.Media;

namespace DatabindingSampleWPF
{
    public class ColorDescriptor : ObservableObject
    {
        public ColorDescriptor(Color color, string name)
        {
            Color = color;
            Name = name;
        }

        public Color Color { get; private set; }

        public string Name { get; private set; }

        public override string ToString()
        {
            return $"{Name} (#{Color.R:X2}{Color.G:X2}{Color.B:X2})";
        }
    }
}

請以上述程式碼取代 ColorDescriptor.cs 檔案的預設內容。

2.建立 ColorList.xaml 頁面

為了顯示色彩清單,我們將使用新的 XAML 檔案。 在 [方案總管] 中,以滑鼠右鍵按一下 DatabindingSampleWPF,然後選取 [新增] / [新項目]。 從可用項目清單中選擇 [Window (WPF)],然後輸入 ColorList 作為名稱。 選取 [新增] 以建立頁面。

[新增項目] 對話方塊的螢幕擷取畫面。

3.設定啟動 XAML 檔案

現在,若啟動應用程式,它會開啟並顯示 [MainWindow]。 由於您將使用新建立的 ColorList.xaml,建議讓它在啟動時顯示。 若要這樣做,請開啟 App.xaml,然後尋找根 Application 元素的 StratupUri 屬性。

StartupUri="MainWindow.xaml"

MainWindow 取代為 ColorList,並確認當您啟動應用程式 (按 F5 或選取 [偵錯] / [開始偵錯]) 時,會顯示 [ColorList]。

顯示空白色彩清單視窗的螢幕擷取畫面。

4.建立色彩清單的 DataContext

我們將繼續使用先前所介紹為新 XAML 視窗建立個別 DataContext 類別的最佳做法。 那麼,請繼續並建立名為 ColorListDataContext 的新類別。

在 [方案總管] 中,以滑鼠右鍵按一下 DatabindingSample 專案,選取 [新增] / [類別],然後輸入 ColorListLogic 作為類別的名稱。 選取 [新增] 以建立類別,並將下列內容貼到檔案中:

using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Windows.Media;

namespace DatabindingSampleWPF
{
    public class ColorListDataContext: ObservableObject
    {
        public List<ColorDescriptor> LotsOfColors { get; private set; }

        public ColorListDataContext()
        {
            LotsOfColors = new List<ColorDescriptor>
            {
               new ColorDescriptor(Colors.Red, "red"),
               new ColorDescriptor(Colors.White, "white"),
               new ColorDescriptor(Colors.Green, "green"),
               new ColorDescriptor(Colors.Yellow, "yellow"),
               new ColorDescriptor(Colors.Blue, "blue"),
               new ColorDescriptor(Colors.Black, "black")
            };

        }
    }
}

ColorListDataContext 類別非常簡單 (至少目前如此)。 它有一個稱為 LotsOfColors 的屬性, 這是 ColorDescriptor 物件的 List。 清單中已填入類別建構函式中的一些色彩。 就是這麼容易!

5.在 ListBox 中顯示色彩

下一步是在我們的應用程式中顯示色彩。 與先前相同,我們將需要在 ColorList.xaml 中建立 ColorListDataContext 類別的執行個體,並將它設定為整個視窗的 DataContext。 請開啟 ColorList.xaml,並在 <Window ...> 標籤的正後方新增此項目:

<Window.DataContext>
    <local:ColorListDataContext/>
</Window.DataContext>

您必須在此時編譯程式碼,以便讓 XAML 設計工具能夠採用新定義的 ColorListDataContext 類別。

接著,請將下列 XAML 複製到 <Grid> 標籤內:

<ListBox ItemsSource="{Binding LotsOfColors}" 
         Margin="20" 
         Width="200"
         HorizontalAlignment="Left" 
         VerticalAlignment="Top"/>

這裡的重點在於 ItemsSource 屬性。 如名稱所示,它提供 ListBox 中所顯示之項目的來源。 而且它直接繫結到 ColorListDataContextLotsOfColors 屬性。

若您現在執行應用程式,它會在 ListBox 中顯示色彩! 但並不太美觀。 ListBox 似乎已叫用儲存在 LotsOfColors 清單中之 ColorDescriptorToString() 方法。

顯示 [色彩清單] 視窗的螢幕擷取畫面,其中列出六種色彩。

6.定義項目的範本

讓範本顯示儲存在 屬性中 ColorDescriptor.Color 的實際色彩,以及其名稱相當好。 就像這樣:

範本的螢幕擷取畫面。

若要在 XAML 中為此撰寫程式碼,我們可以在 StackPanel 中放置已上色的 RectangleTextBlock

<StackPanel Orientation="Horizontal">
    <Rectangle Width="80" Height="20">
        <Rectangle.Fill>
            <SolidColorBrush Color="Blue"/>
        </Rectangle.Fill>
    </Rectangle>
    <TextBlock Text="blue" Margin="20, 10, 0, 10"/>
</StackPanel>

這是 XAML 與資料繫結的其中一個強項。 幾乎所有複雜視覺效果都是以您可以重新定義的範本為基礎。 若要使用上面的 StackPanel 做為範本,我們必須將它放在 DataTemplate 內。 DataTemplate 必須定義 DataType,這是可做為範本套用目標的資料類型。 在我們的案例中,它是 ColorDescriptor 類別。 因此,DataTemplate 看起來像這樣:

<DataTemplate x:DataType="local:ColorDescriptor">
    <!-- template content comes here -->
</DataTemplate>

資料在 ListBox (以及許多其他控制項) 中的呈現方式,是由其 ItemTemplate 所控制,這應該設定為 DataTemplate。 有多種方法可以這麼做。 在此課程中,我們會簡單地使用下列語法在 ListBox 內定義 DataTemplate

<ListBox ...>
    <ListBox.ItemsSource>
        <DataTemplate ...>
            ...
        </DataTemplate>
    </ListBox.ItemsSource>
</ListBox>

稍後,您將會看到如何透過將 DataTemplate 定義為資源,來在多個地方重複使用它。

現在,整個 ListBox 看起來像這樣 (若您還沒有跟著這樣做,請使用下列 XAML 取代整個 <ListBox> 標記):

<ListBox ItemsSource="{Binding LotsOfColors}" 
         Margin="20" 
         Width="200"
         HorizontalAlignment="Left" 
         VerticalAlignment="Top">
    <ListBox.ItemTemplate>
        <DataTemplate x:DataType="local:ColorDescriptor">
            <StackPanel Orientation="Horizontal">
                <Rectangle Width="80" 
                           Height="20">
                    <Rectangle.Fill>
                        <SolidColorBrush Color="{Binding Color}"/>
                    </Rectangle.Fill>
                </Rectangle>
                <TextBlock Text="{Binding Name}" 
                           Margin="20, 10, 0, 10"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

請注意,因為 ListBox 中的每個項目都對應到 ColorDescriptor 物件,您只需要在此類別內容內的範本內定義繫結。

7.執行應用程式

您應該會在 Visual Studio 中立即看到色彩清單。 作為確認,請按 F5 或選取功能表中的 [偵錯] > [開始偵錯] 來立即執行應用程式。

顯示 [色彩清單] 視窗的螢幕擷取畫面,其中六個色彩列在代表色彩的矩形旁邊。

如果您以偵錯模式啟動 XAML 應用程式,便可以利用即時 XAML 編輯功能。 您甚至無須停止應用程式或按 [儲存]。 只須變更 XAML,絕大多數的變更就會立即反映在執行中的應用程式上。 試試看吧。 將資料範本內 RectangleWidthHeight 變更為 30,藉此將彩色矩形轉換成正方形。

顯示 [色彩清單] 視窗的螢幕擷取畫面,其中六個色彩列在代表色彩的正方形旁邊。

這稱為XAML 熱重新載入,它對於微調應用程式中的配置和動畫很有用。

摘要

此課程已說明在 ListBox 中顯示多個項目的基本概念。 還有其他相似用途的控制項可供使用,例如 ItemsControlListViewGridView。 但其基本原理都相同:將您的物件清單 (IEnumerableList<>) 繫結至 ItemsSource 屬性,然後定義 DataTemplates 以控制個別清單項目的顯示方式和行為模式。 您也可以重新定義這些項目的配置,甚至是容器控制項本身的外觀 (不過這已超出此課程模組的範圍)。

請注意,程式碼本身一律不須處理 ListBox 本身。 它只須建立商務物件 (ColorDescriptor) 的集合,XAML 執行階段便會負責擴充每個項目的範本。

下個課程會說明如何從 ListBox 或下拉式清單中選取項目,以及從程式碼變更清單內容,以便讓元素的新增和移除反映在 UI 上。