none
Problem binding ComboBox ToolTip to selected item

    Question

  • I'm trying to display information about the currently selected item in a ComboBox using a ToolTip.  Can anyone tell me why in the example code below, the Binding works fine on the TextBlock, but using the same binding for the combo's ToolTip doesn't work (the tooltip is always empty)?

    I get the exception:

    Cannot find source for binding with reference 'ElementName=combo'

    but only the tooltip binding has that problem, the TextBlock works fine.

    I've tried all the various ways of accessing the selected item/value on the combo and various options on the Binding and I just can't seem to make this work...

    <ComboBox x:Name="combo" HorizontalAlignment="Center" VerticalAlignment="Top" Width="Auto" SelectedIndex="0">  
     
            <ComboBoxItem>one</ComboBoxItem> 
            <ComboBoxItem>two</ComboBoxItem> 
            <ComboBoxItem>three</ComboBoxItem> 
     
            <ComboBox.ToolTip> 
                <ToolTip Content="{Binding ElementName=combo, Path=SelectionBoxItem}" /> 
            </ComboBox.ToolTip> 
     
        </ComboBox> 
     
        <TextBlock Margin="0,40,0,0" Text="{Binding ElementName=combo, Path=SelectionBoxItem}" HorizontalAlignment="Center" /> 
     
     
    • Edited by matte303 Thursday, July 31, 2008 6:45 PM correction
    Thursday, July 31, 2008 6:17 PM

Answers

  • The following XAMLPad ready example demonstrates how to enable data binding on ToolTip:

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <DockPanel>
            <ComboBox x:Name="combo" SelectedIndex="0" DockPanel.Dock="Top">
                <ComboBoxItem>one</ComboBoxItem>
                <ComboBoxItem>two</ComboBoxItem>
                <ComboBoxItem>three</ComboBoxItem>
               
                <ComboBox.ToolTip>
                    <ToolTip DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
                        <TextBlock Text="{Binding SelectionBoxItem}" Foreground="Green"/>
                    </ToolTip>
                </ComboBox.ToolTip>
           
            </ComboBox>
           
            <TextBlock
                Margin="0,40,0,0" Text="{Binding ElementName=combo, Path=SelectionBoxItem}"
                HorizontalAlignment="Center" />
        </DockPanel>
    </Page>

    Hope this helps
    • Marked as answer by matte303 Tuesday, August 05, 2008 2:21 PM
    Tuesday, August 05, 2008 3:45 AM

All replies

  • I think it is because the ToolTip is within property tags, placing it a context seperate from the otehr elements...but i'm not sure exactly how and why it's like that.

    Did you try this as well?
    <ComboBox x:Name="combo" ToolTip="{Binding ElementName=combo, Path=SelectionBoxItem}"/>
    Thursday, July 31, 2008 9:49 PM
  • yes that works correctly but I can't use that approach. My tooltip will be composited with multiple bits of text so I need to use Property Element syntax to define it:

    sorta like this:

    <ComboBox.ToolTip> 
        <ToolTip> 
            <StackPanel> 
                <TextBlock Text="{Binding Path=SelectedItem.Name, ElementName=comboBox}" /> 
                <TextBlock Text="{Binding Path=SelectedItem.Description, ElementName=comboBox}" /> 
                <TextBlock Text="{Binding Path=SelectedItem.Location, ElementName=comboBox}" /> 
            </StackPanel> 
        </ToolTip> 
    </ComboBox.ToolTip> 
     
    Thursday, July 31, 2008 9:59 PM
  • So no one can tell me why setting the ToolTip with a Binding works fine using Attribute syntax, but the exact same Binding fails when specified using Property Element syntax??? This seems like a WPF  bug to me...
    Monday, August 04, 2008 6:47 PM
  • Hello, I tried to use C# code to set the ToolTip dynamically, it works ok. I guess there are something wrong about the visual tree of Binding ToolTip.

    <ComboBox  SelectionChanged="ComboBox_SelectionChanged" x:Name="combo" 
        HorizontalAlignment="Center" VerticalAlignment="Top" Width="Auto"
            <ComboBoxItem>one</ComboBoxItem> 
            <ComboBoxItem>two</ComboBoxItem> 
            <ComboBoxItem>three</ComboBoxItem> 
    </ComboBox> 

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
                ComboBox cb = sender as ComboBox; 
                ToolTip tip = new ToolTip(); 
                StackPanel sp = new StackPanel(); 
                sp.Children.Add(new TextBlock(new Run(cb.SelectedValue.ToString()))); 
                sp.Children.Add(new TextBlock(new Run(cb.SelectedValue.ToString()))); 
                tip.Content = sp
                (sender as ComboBox).ToolTip = tip

    Hope this helps




    Yiling, MVP(Visual C++)
    Tuesday, August 05, 2008 1:18 AM
  • The following XAMLPad ready example demonstrates how to enable data binding on ToolTip:

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <DockPanel>
            <ComboBox x:Name="combo" SelectedIndex="0" DockPanel.Dock="Top">
                <ComboBoxItem>one</ComboBoxItem>
                <ComboBoxItem>two</ComboBoxItem>
                <ComboBoxItem>three</ComboBoxItem>
               
                <ComboBox.ToolTip>
                    <ToolTip DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
                        <TextBlock Text="{Binding SelectionBoxItem}" Foreground="Green"/>
                    </ToolTip>
                </ComboBox.ToolTip>
           
            </ComboBox>
           
            <TextBlock
                Margin="0,40,0,0" Text="{Binding ElementName=combo, Path=SelectionBoxItem}"
                HorizontalAlignment="Center" />
        </DockPanel>
    </Page>

    Hope this helps
    • Marked as answer by matte303 Tuesday, August 05, 2008 2:21 PM
    Tuesday, August 05, 2008 3:45 AM
  • Great, Thanks Marco. I got it, if I am wrong, please correct me. Due to ToopTip is rendered in another separate window, we used RelativeSource.Self as the data source of binding isn't work. The return value of RelativeSource.Self if ToolTip element, not the ComboBox element. So the previous binding failed and my C# code works ok.  With the help of PlacementTarget property we can get the ComboBox element as data source. then binding to SelectionBoxItem works ok now.

    Thanks again.

    Yiling, MVP(Visual C++)
    Tuesday, August 05, 2008 4:16 AM
  • Yiling and Marco, thank you for your help.  Configuring the Binding with RelativeSource and PlacementTarget works perfectly. I suspected the problem was as Yiling describes (that RelativeSource.Self points to the ToolTip, not the ComboBox), that's why I tried setting the Binding using ElementName instead (see my code block in the first post), I'm still not sure I understand why that didn't work, but I have a working solution now, thanks again!
    Tuesday, August 05, 2008 2:27 PM
  • The real problem here is that ToolTip alongside with ContextMenu will be treated as random properties for FrameworkElements, so ToolTip and ConextMenu will not be part of the element tree (either logical tree or visual tree), from my personal understanding, this could get some of the performance benefits, since when you shows a ToolTip or ContextMenu, you don't need to add them into the main element tree, and remove them when they are hidden. (note that big structure change within visual tree doesn't come for free).

    But the problem with this is that ElementName binding which replies on traversal of the logical tree to find the correct name scope to resolve the name of the element will fails, because any content within ToolTip and ContextMenu resides in their own element tree which is different from the main element tree.

    Fortunately, PlacementTarget is a good property to help us bridge between main element tree and the element tree presented by ToolTips and ContextMenus.

    I have to say that all those implementation details should be hidden from developers, and it would be better if WPF could come up with a method to hide such details, and make data binding work as it is with other typical scenario.

    Hopefully, future version of WPF could address this in a profound way.

    Hope this clears things up a little bit.
    Wednesday, August 06, 2008 3:30 AM
  • yes, it makes sense now why ElementName doesn't work in this situation, thanks for the explanation!
    Wednesday, August 06, 2008 1:21 PM
  • I don't know how nobody mentioned this, but all you need is to add a style in the combobox resources for ComboBoxItems that specifies the tooltip binding:

    If you were hard coding items:
      <ComboBox>
        <ComboBoxItem Content="EUR" ToolTip="Euro" />
        <ComboBoxItem Content="USD" ToolTip="United States Dollars" />
        <ComboBoxItem Content="CAD" ToolTip="United Kingdom Pounds" />
        <ComboBoxItem Content="GBP" ToolTip="Canadian Dollars" />
        <ComboBoxItem Content="JPY" ToolTip="Japan Yen" />
      </ComboBox>
    


    If you're using bindings:
      <ComboBox Text="{Binding Path=Currencies.SelectedCurrency.CurrencyCode}"
           ItemsSource="{Binding Path=Currencies.CurrencyList}"
           SelectedItem="{Binding Path=Currencies.SelectedCurrency}"<br/>
           ToolTip="{Binding Path=Currencies.SelectedCurrency.CurrencyName}"<br/>
           DisplayMemberPath="CurrencyCode">
        <ComboBox.Resources>
          <Style TargetType="ComboBoxItem">
            <Setter Property="ToolTip" Value="{Binding Path=CurrencyName}" />
          </Style>
        </ComboBox.Resources>
      </ComboBox>
    
    Note that the Tooltip binding for the combobox is when you mouse over the drop down area, and the style is for when you mouse over the individual items in the popup list.
    Thursday, August 05, 2010 4:59 PM
  • Hi

    I'm trying since quite some time to fgure how to add a DataTemplate for ToolTip, to BOTH ComboxItem AND SelectedItem, within a <Style TargetType="ComboBox"/> in the resources. The Comboboxs are bound to a BindingListCollectionView, which last column "Description"  contains Concats(all nonNULL fields)). I'm trying to fill the ToolTip Content with descriptive infos from that column, in a organized visual way.

    My problem seems very similar to the examples provided by MarcoZhou and AlainBryden in this topic.

    The DataTemplate :

    <DataTemplate x:Key="ToolTipContent">
     <DockPanel Width="150">
      	<Image DockPanel.Dock="Left"/>
      	<StackPanel DockPanel.Dock="Top">
      		 <DockPanel>
      			<TextBlock Text="{Binding Names}" DockPanel.Dock="Left" TextAlignment="Left" FontSize="14" FontWeight="Bold"/>
      			<TextBlock Name="Rarity" DockPanel.Dock="Right" TextAlignment="Right"/>
      		</DockPanel>
      		<TextBlock Text="{Binding Description}" TextWrapping="Wrap"/>
      	</StackPanel>
     </DockPanel>
    	<DataTemplate.Triggers>
      	<DataTrigger Binding="{Binding Rare}">
      		<DataTrigger.Value>True</DataTrigger.Value>
      		<Setter TargetName="Rarity" Property="Text" Value="Rare"/>
     	</DataTrigger>
    	</DataTemplate.Triggers>
    </DataTemplate>
    

    Can someone help to find the correct syntax please ?

    So far i only managed to implement a Style for CombobxItem only, which directly uses same syntax as the above DataTemplate. It works if SelectedItem=NULL, but otherwise the following exception is raised :

    "Specified element is already the logical child of another element. Disconnect it first."



    Monday, May 30, 2011 9:26 AM