在 ListBox 中使用 DataTemplate

假設我們有以下 XAML 片段:

<ListBox x:Name="MyListBox" />

然後在這個 XAML 檔案的程式碼隱藏中,我們在建構函式中編寫以下內容:

MyListBox.ItemsSource = new[]
{
    1, 2, 3, 4, 5
};

執行應用程式,我們得到一個我們輸入的數字列表。

StackOverflow 文件

但是,如果我們嘗試顯示自定義型別的物件列表,就像這樣

MyListBox.ItemsSource = new[]
{
    new Book { Title = "The Hitchhiker's Guide to the Galaxy", Author = "Douglas Adams" },
    new Book { Title = "The Restaurant at the End of the Universe", Author = "Douglas Adams" },
    new Book { Title = "Life, the Universe and Everything", Author = "Douglas Adams" },
    new Book { Title = "So Long, and Thanks for All the Fish", Author = "Douglas Adams" },
    new Book { Title = "Mostly Harmless", Author = "Douglas Adams" }
};

假設我們有一個名為 Book 的類

public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }
}

然後列表看起來像這樣:

StackOverflow 文件

雖然我們可以假設 ListBox 將足夠智慧來恰當地顯示我們的書籍物件,但我們實際看到的是 Book 型別的全名。ListBox 實際上在這裡做的是在它想要顯示的物件上呼叫內建的 ToString() 方法,雖然在數字的情況下產生了理想的結果,但在自定義類的物件上呼叫 ToString() 會導致獲得其型別的名稱,如在截圖上看到。

我們可以通過為我們的書類編寫 ToString() 來解決這個問題,即

public override string ToString()
{
    return Title;
}

StackOverflow 文件

但是,這不是很靈活。如果我們想要展示作者怎麼辦?我們也可以將它寫入 ToString,但如果我們不想在應用程式的所有列表中呢?如何展示漂亮的書籍封面?

這就是 DataTemplates 可以提供幫助的地方。它們是 XAML 的片段,可以根據需要例項化,根據建立的源資料填充詳細資訊。簡單地說,如果我們擴充套件 ListBox 程式碼如下:

<ListBox x:Name="MyListBox">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Title}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

然後列表將為其源中的每個項建立一個 TextBox,這些 TextBox 將使用來自我們物件的 Title 屬性的值填充Text 屬性。

如果我們現在執行應用程式,我們將得到與上面相同的輸出,*即使我們刪除自定義 ToString 實現。對此有利的是,我們可以自定義此模板,遠遠超出簡單的 string(和 ToString)的功能。我們可以使用我們想要的任何 XAML 元素,包括自定義元素,並且可以將它們的值繫結到來自物件的實際資料(如上例中的 Title)。例如,按如下方式擴充套件模板:

<ListBox x:Name="MyListBox">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock FontStyle="Italic" Text="{Binding Author}" />
                <TextBlock FontSize="18" Text="{Binding Title}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

然後我們得到了一個很好的格式化的書籍檢視!

StackOverflow 文件