Jak zobrazit ToolTip nad vlastním objektem v ListBoxu

Teď jsem se trochu zasekl na vytváření ToolTipů na každé položce ListBoxu, a na štěstí mě přivedly i některé rady na webu, ale o tom až níže. Celý kód je tentokrát velice primitivní. Prvně si vytvoříme ListBox, se šablonou, která bude zobrazovat TextBlock a nad ním ToolTip. Data budeme brát pomocí Data Bindingu:

XML
<ListBox x:Name="lbSongs" Height="160" MaxHeight="160" Margin="0" Padding="0">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=FileName}">
                <ToolTipService.ToolTip>
                    <TextBlock Text="{Binding Path=DirectoryName}"></TextBlock>
                </ToolTipService.ToolTip>
            </TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Problém s některými články na webu byl ten že jsem chtěl použít přímo <ToolTip> místo <ToolTipService.ToolTip> s vnitřním TextBlockem a pak mi to házelo tuto výjimku: Add value to collection of type 'System.Windows.Documents.InlineCollection' threw an exception.. Druhým krokem je pak vytvoření vlastní třídy, která bude obsahovat vlastnosti DirectoryName a FileName, tak jak jsou zmiňovány v XAMLu. Metoda FS.GetPathAndFileName je velice jednoduchá, pouze vrací pomocí out výstup metody Path.GetDirectoryName() a Path.GetFileName():

C#
using System.Windows.Controls;
using System.Windows.Documents;
class Song
{
    public Song(string fullFilePath)
    {
        string p, s;
        FS.GetPathAndFileName(fullFilePath, out p, out s);
        FileName = s;
        DirectoryName = p;
    }
    public string FileName
    {
        get
        ;
        set
        ;
    }
    public string DirectoryName
    {
        get
        ;
        set
        ;
    }
    public override string ToString()
    {
        return FileName;
    }
}

Posledním krokem je naplnění ListBoxu, to samozřejmě provedeme v Code-Behindu:

C#
public RightToolTipApproachForCustomObjects()
{
    InitializeComponent();
    PopulateListBox();
}
void PopulateListBox()
{
    List<Song> songs = new List<Song>();
    songs.Add(new Song(@"C:\Users\sunamo\Desktop\Dolcezza 1.mp3"));
    songs.Add(new Song(@"C:\Users\sunamo\Desktop\Dolcezza 2.mp3"));
    lbSongs.ItemsSource = songs;
}

Finální výsledek může pak vypadat nějak takto:



Samozřejmě u vás to nemusí vypadat takhle, ale jednodušeji, v programu z kterého se čerpá pro tuto ukázku totiž používám styly z Windows Store Apps.

Napsat komentář