Sök…


Använda DataTemplate i en ListBox

Anta att vi har följande XAML-utdrag:

<ListBox x:Name="MyListBox" />

Sedan i koden bakom denna XAML-fil skriver vi följande i konstruktören:

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

När du kör applikationen får vi en lista med siffror vi har angett.

ange bildbeskrivning här

Men om vi försöker visa en lista med objekt av en anpassad typ, så här

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" }
};

förutsatt att vi har en klass som heter Book

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

då skulle listan se ut så här:

ange bildbeskrivning här

Även om vi kan anta att ListBox är "tillräckligt smart" för att visa våra bokobjekt precis rätt, är det vi faktiskt ser hela namnet på Book . Vad ListBox faktiskt gör här är att kalla den inbyggda ToString() -metoden på objekt som den vill visa, och även om det ger det önskvärda resultatet i fallet med nummer, ringer ToString() på objekt av anpassade klasser resulterar i att få namnet på deras typ, som visas på skärmdumpen.

Vi kan lösa det genom att skriva ToString() för vår ToString() , dvs.

public override string ToString()
{
    return Title;
}

ange bildbeskrivning här

Men det är inte särskilt flexibelt. Vad händer om vi också vill visa författaren? Vi kan skriva det i ToString också, men vad ToString om vi inte vill ha det i alla listor i appen? Vad sägs om ett trevligt bokomslag att visa?

Det är där DataTemplates kan hjälpa. Det är utdrag av XAML som kan "instanseras" vid behov, fyllda med detaljer beroende på källdata de skapas för. Enkelt uttryckt, om vi utökar vår ListBox-kod enligt följande:

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

då kommer listan att skapa en TextBox för varje objekt i dess källa, och dessa TextBoxer kommer att ha sina Text "fyllda" med värden från egenskapen Title för våra objekt.

Om vi kör applikationen nu får vi samma output som ovan, * även om vi tar bort den anpassade ToString implementeringen. Det som är fördelaktigt med detta är att vi sedan kan anpassa den här mallen långt utöver funktionerna i en enkel string (och ToString ). Vi kan använda alla XAML-element vi vill, inklusive anpassade, och kan "binda" deras värden till faktiska data från våra objekt (som Title i exemplet ovan). Förläng exempelvis mallen enligt följande:

<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>

Då får vi en fin formaterad vy av våra böcker!

ange bildbeskrivning här



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow