Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom WPF tooltip

Tags:

wpf

tooltip

I want to create a WPF tooltip containing a label for the header of the tooltip and then a textblock containing more detailed text. I've created the following style in a resource dictionary:

<Style x:Key="AppToolTip"
   TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true" />    
<Setter Property="Template">
        <Setter.Value>

            <ControlTemplate TargetType="ToolTip">
                <StackPanel>
                    <Label Content="{TemplateBinding Content}" FontWeight="Bold" Background="Blue" Foreground="White">

                    </Label>
                    <TextBlock Padding="10" TextWrapping="WrapWithOverflow" Width="200">

                    </TextBlock>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value></Setter>
</Style>

And can successfully apply this style to a button like so and have the tooltip header appear:

<Button.ToolTip>
<ToolTip Style="{DynamicResource PalletToolTip}">
                    <Binding Source="{x:Static ResStrings.New}"/>
                </ToolTip>
</Button.ToolTip>

What i'm stuck on is how can i set the content of the extra descriptive text from the usage above ? I'm already data binding to the Content property when showing the tooltip header. Anyone who's read Adam Nathan's WPF Unleashed book will recognise that i'm using his example tooltip XAML but in his case, he's used hard coded strings for the content of the label and textblock. I want to create something that's more reusable and hence want to use data binding to achieve the same effect.

like image 368
Auburg Avatar asked Jul 05 '11 12:07

Auburg


2 Answers

I would inherit a HeaderedToolTip class from ToolTip and add a Header property. I would specify the template for that control much as you've done. Then I would be able to use it like so:

<Button>
    <Button.ToolTip>
        <HeaderedToolTip Header="My Title" Content="My Content"/>
    </Button.ToolTip>
</Button>

Or, with bindings:

<Button>
    <Button.ToolTip>
        <HeaderedToolTip Header="{Binding ToolTipTitle}" Content="{Binding ToolTipText}"/>
    </Button.ToolTip>
</Button>
like image 180
Kent Boogaart Avatar answered Sep 30 '22 09:09

Kent Boogaart


You can use an object or ViewModel that contains all the necessary properties you need in the tooltip.

class MyToolTipViewModel : INotifyPropertyChanged
{
    public string Header
    {
       get{ return mHeader;}
       set{ mHeader = value; RaisePropertyChanged("Header"); }
    }

    public void RaisePropertyChanged(string aProperty)
    {
     // .. implementation of INotifyPropertyChanged
    }
}

then you can set the tolltip directly on an instance of this class.

myButton.ToolTip = new MyToolTipViewModel();

now after that, your tooltip will just show the full qualified name of the ViewModel class. What you need now is a DataTemplate, which tells WPF how to convert the class into visual object.

<DataTemplate DataType="{x:Type MyToolTipViewModel}">
    <TextBlock Text="{Binding Header}"/>
</DataTemplate>

The DataTemplate need to be placed in the resource tree. In the resource section of a higher level object or directly on the application or window resources level.

Hope that helps.

like image 31
dowhilefor Avatar answered Sep 30 '22 08:09

dowhilefor