I've come accross a little issue that I'm unable to explain/solve :x (Well solving can be done by not putting the tooltip in the resources and duplicate the tooltip code but it will not be a good solution in my opinion)
What I'm trying to achieve is to have a tooltip shown ONLY when the text is trimmed. There is plenty of solutions online. The probleme doesn't lie there :)
The issue is that I'm putting the tooltip in resource (hence only have 1 tooltip object) and then, it looks like the width of the tooltip is not recalculated/refreshed as it should.
PS : I've set this size for the window (to be sure to have trimming)
Height="100" Width="200"
Let's see the code :
<Window.Resources>
<converters:TextTrimmedToVisibilityConverter x:Key="TextTrimmedToVisibilityConverter" />
<ToolTip x:Key="TrimmedTooltip"
DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}"
Visibility="{Binding ., Converter={StaticResource TextTrimmedToVisibilityConverter}}">
<ToolTip.Content>
<TextBlock Text="{Binding Text}" />
</ToolTip.Content>
</ToolTip>
</Window.Resources>
<Grid>
<StackPanel>
<TextBlock Text="Text 1" TextTrimming="CharacterEllipsis" ToolTip="{StaticResource TrimmedTooltip}" />
<TextBlock Text="blablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla" TextTrimming="CharacterEllipsis" ToolTip="{StaticResource TrimmedTooltip}" />
</StackPanel>
</Grid>
And here is the converter :
public class TextTrimmedToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return Visibility.Collapsed;
// Retrieve the TextBlock which may need the tooltip (PlacementTarget of the ToolTip)
FrameworkElement fe = (FrameworkElement)value;
// Measure it without the eventual trimming to get the exact desired size
fe.Measure(new System.Windows.Size(Double.PositiveInfinity, Double.PositiveInfinity));
// Now we know if the tooltip needs to be displayed
if (fe.ActualWidth < fe.DesiredSize.Width)
return Visibility.Visible;
else
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
And the behavior that is wrong can be obtained by :
- Hover 'Text 1' -> (No tooltip) < OK
- Hover 'blablablabla.....' -> (tooltip) < OK
- Hover 'Text 1' -> (No tooltip) < OK
- Hover 'blablablabla.....' -> (tooltip) < but only display blabla (based I think on the width of 'Text 1') NOT OK
- Hover 'Text 1' -> (No tooltip) < OK
- Hover 'blablablabla.....' -> (tooltip) < OK (Back to the normal state)
- Hover 'Text 1' -> (No tooltip) < OK
- Hover 'blablablabla.....' -> (tooltip) < but only display blabla (based I think on the width of 'Text 1') NOT OK
- Move mouse under 'blablabla...' and come hover 'blablabla' again -> (tooltip but still small size...) NOT OK
- Repeat until you are tired :x
So the problem is cause by the fact that I'm reusing the same tooltip (because the width of the tooltip somehow is not refreshed while the bindings are corrects)
Can anyone explain me this ? and how can I have the width being updated no matter what ?
Thanks in advance gurus!
Gaël
PS : I'm using VS 2010 SP1 and the project is .NET 4 Client Profile
Edit : answer posted