Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Tooltip Binding

I am only two weeks into WPF so this is probably a trivial question. I have a collection "CellList" which has a few properties I would like to bind to a ToolTip so when I hover over a label information from the current instance of CellList is displayed. How do I do that? I understand simple binding and this maybe simple binding too but I can't wrap my head around it. Below is my XAML for the label. Could someone explain to me how I can accomplish this.

<HierarchicalDataTemplate>
      <ListBox ItemsSource="{Binding CellList}">
           <ListBox.ItemTemplate>
               <DataTemplate>
                 <Label Content=" " Height="20" Width="15" Background="{Binding Path=ExptNameBkg, Converter={StaticResource ExptNameToBrushConverter}}"                                                   BorderBrush="Black" BorderThickness="1" >
                  </Label>  
              </DataTemplate>                                    
            </ListBox.ItemTemplate>   
       </ListBox>
</HierarchicalDataTemplate>

Thanks.

like image 342
Nathan Avatar asked Feb 06 '10 05:02

Nathan


3 Answers

The tricky thing about ToolTips is that a ToolTip is an object you associate with a control, and not part of the control's visual tree. So you can't populate it the way you'd populate things in the visual tree, e.g.:

<TextBox.ToolTip>
   <StackPanel>
      ...put bound controls here
   </StackPanel>
</TextBox.ToolTip>

Instead, what you have to do is create a specific instance of a ToolTip, and assign it a style that sets its DataContext (very important; that's how you can bind to the properties of the data source of its "placement target," i.e. the control that's displaying the tooltip) and its Template. Then put the visual tree of the ToolTip, including bindings, into the template. Finally, reference the ToolTip in your control.

So, here's a TextBox whose Binding does validation:

<TextBox ToolTip="{StaticResource ErrorToolTip}">
    <TextBox.Text>
        <Binding Source="SourceProperty">
            <Binding.ValidationRules>
               <DataErrorValidationRule/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

It uses this ToolTip:

<ToolTip x:Key="ErrorToolTip" Style="{StaticResource ErrorToolTipStyle}"/>

And the ToolTip uses this style, which gets its content from the ValidationError property of the TextBox's binding source:

<Style x:Key="ErrorToolTipStyle" TargetType="{x:Type ToolTip}">
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="HasDropShadow" Value="True"/>
    <Setter Property="DataContext" Value="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToolTip">
                <Border
                    Name="Border" 
                    BorderThickness="1" 
                    BorderBrush="LightGray">
                    <StackPanel Orientation="Vertical">
                        <Label Background="Firebrick" Foreground="White" FontWeight="Bold" Margin="4">Validation error</Label>
                        <TextBlock Margin="10" Text="{Binding ValidationError}"/>
                    </StackPanel>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasDropShadow" Value="true">
                        <Setter TargetName="Border" Property="CornerRadius" Value="4"/>
                        <Setter TargetName="Border" Property="SnapsToDevicePixels" Value="true"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I'm not certain of this, but I think that the only part of the above that actually has to be set in the style is the DataTrigger setting the DataContext; I think most everything else could just be explicitly set in the ToolTip's visual tree. But I'm probably not thinking of something important.

like image 110
Robert Rossney Avatar answered Sep 21 '22 00:09

Robert Rossney


<Label Content={Binding Path=Id} ToolTip={Binding Path=Name}/>

just try this

like image 25
Kishore Kumar Avatar answered Sep 23 '22 00:09

Kishore Kumar


Here's a kaxaml-ready example that includes a tooltip that is a little more elaborate than just text:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
    <XmlDataProvider x:Key="CharacterData">
      <x:XData>
        <Data xmlns="">
          <Character First="Bart" Last="Simpson" Background="LightGreen" />
          <Character First="Homer" Last="Simpson" Background="LightBlue" />
          <Character First="Lisa" Last="Simpson" Background="Pink" />
          <Character First="Maggie" Last="Simpson" Background="Yellow" />
          <Character First="Marge" Last="Simpson" Background="PapayaWhip" />
        </Data>
      </x:XData>
    </XmlDataProvider>
    <ToolTip x:Key="ElaborateToolTip">
      <Grid Margin="5">
        <Rectangle RadiusX="6" RadiusY="6" Fill="{Binding XPath=@Background}" />
        <StackPanel Orientation="Horizontal" Margin="10">
          <TextBlock Text="{Binding XPath=@First}" Margin="0,0,6,0" />
          <TextBlock Text="{Binding XPath=@Last}" />
        </StackPanel>
      </Grid>
    </ToolTip>
  </Page.Resources>
  <ListBox ItemsSource="{Binding Source={StaticResource CharacterData}, XPath=Data/Character}">
    <ListBox.ItemContainerStyle>
      <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="ToolTip" Value="{StaticResource ElaborateToolTip}" />
      </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
      <DataTemplate>
        <TextBlock Text="{Binding XPath=@First}" />
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</Page>
like image 5
Dr. WPF Avatar answered Sep 25 '22 00:09

Dr. WPF