2
votes

I've got a ListBox that displays an ObservableCollection of Talent objects. When the user hovers over each item in the ListBox, I'd like to display in the ToolTip several pieces of information about the Talent.

My ListBox:

<ListBox ItemsSource="{Binding ElementName=CE_Races_racesLB, Path=SelectedItem.Talents}" ItemTemplate="{StaticResource removableTalentListTemplate}" />

The ItemTemplate:

<DataTemplate x:Key="removableTalentListTemplate">
    <StackPanel>
        <TextBlock FontSize="13" Text="{Binding Path=tName}" VerticalAlignment="Center" Width="175" Height="18" Grid.Column="0" />
    </StackPanel>
</DataTemplate>

I can display the Description of the Talent if I add ToolTipService.ToolTip="{Binding Path=Description" to the TextBlock properties. However, when I try to create a custom ToolTip like such:

<DataTemplate x:Key="removableTalentListTemplate">
    <StackPanel>
        <TextBlock FontSize="13" Text="{Binding Path=tName}" VerticalAlignment="Center" Width="175" Height="18" Grid.Column="0" />
            <TextBlock.ToolTip>
                <ToolTip>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Description}" />
                    </StackPanel>
                </ToolTip>
            </TextBlock.ToolTip>
        </TextBlock>
    </StackPanel>
</DataTemplate>

When I go to mouseover the ListBox item, the tooltip just says "System.Windows.Controls.StackPanel". I'd really like to create a nice ToolTip showing lots of info but I can't get past this roadblock. Here's a screenshot of what it looks like now: http://silkforge.com/dev/ss.jpg. You can't see the mouse, but you can see the tooltip just under the ListBox item "Acute Hearing I".

3
Did you ever find a solution to this? I am experiencing this same thing, however, with a twist: in the same WPF app, using the same Border control, copied and pasted into two different screens: one instance exhibits this problem and the other works exactly as it's supposed to. I'll dig more into this...BCA

3 Answers

5
votes

Have you tried this?

<TextBlock Text="{Binding Path=tName}">
  <ToolTipService.ToolTip>
    <StackPanel>
      <TextBlock Text="{Binding Path=Description}" />
    </StackPanel>
  </ToolTipService.ToolTip>
</TextBlock>
2
votes

After a quick test your code seems to work fine.

My test:

xaml:

 <Window x:Class="WpfApplication4.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication4"
            xmlns:Controls="clr-namespace:Liz.Common"
           Title="MainWindow" Height="300" Width="400" Name="UI" >

 <Window.Resources>
    <DataTemplate x:Key="removableTalentListTemplate">
            <StackPanel>
                <TextBlock FontSize="13" Text="{Binding Path=tName}" VerticalAlignment="Center" Width="175" Height="18" Grid.Column="0" >
                    <TextBlock.ToolTip>
                        <ToolTip Background="Blue">
                            <StackPanel>
                                <TextBlock Text="{Binding Path=Description}" Foreground="White" />
                            </StackPanel>
                        </ToolTip>
                    </TextBlock.ToolTip>
                </TextBlock>
            </StackPanel>
        </DataTemplate>
     </Window.Resources>

        <Grid>
            <ListBox ItemTemplate="{StaticResource removableTalentListTemplate}" ItemsSource="{Binding ElementName=UI, Path=Models}" />
        </Grid>
    </Window>

Code:

public partial class MainWindow : Window
{
    private ObservableCollection<MyModel> _models = new ObservableCollection<MyModel>();

    public MainWindow()
    {
        InitializeComponent();
        Models.Add(new MyModel { tName = "Test", Description = "Hello" });
    }

    public ObservableCollection<MyModel> Models
    {
        get { return _models; }
        set { _models = value; }
    }
}

public  class MyModel : INotifyPropertyChanged
{
    private string _tName;
    private string _description;

    public string tName 
    {
        get { return _tName; }
        set { _tName = value; NotifyPropertyChanged("tName"); } 
    }

    public string Description
    {
        get { return _description; }
        set { _description = value; NotifyPropertyChanged("Description"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

result: enter image description here

0
votes

I don't know whether I've experience the same issue as the OP, but the source of trouble for me was the following implicit style:

<Style TargetType="{x:Type ToolTip}">
   <Setter Property="ContentTemplate">
       <Setter.Value>
           <DataTemplate>
               <TextBlock TextWrapping="Wrap" Text="{Binding}" MaxWidth="600"/>
           </DataTemplate>
       </Setter.Value>
   </Setter>
</Style>

The purpose of this style was to eliminate long-winded tooltips from exceeding viewable screen area, but it only works on standard, inline tooltips. Attempting to create a custom, elaborate tooltip resulted in the "System.Windows.Controls.StackPanel" that the OP reported. Removing this implicit style immediately resolved the issue... however also removes the nice 600 DIP width restriction.