views:

1977

answers:

4

I have a TextBlock inside a limited-size control. If the text is too long to fit into the control, I'd like to show a tooltip with full text. This is a classic behavior you surely know from many apps.

I tried using a Converter to convert TextBlock width into Tooltip's Visibility.

<GridViewColumn.CellTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Text}">
            <TextBlock.ToolTip>
                <ToolTip 
                    DataContext="{TemplateBinding Content}" 
                    Visibility="{Binding Converter={StaticResource visConvert}}">

                        <TextBlock Text="{Binding Text}"></TextBlock>
                </ToolTip>
            </TextBlock.ToolTip>
        </TextBlock>
    </DataTemplate>
</GridViewColumn.CellTemplate>

The problem is that in the Converter:

public object Convert(object value, ...

'value' is the DataBound item. I'd like the 'value' to be the TextBlock, to observe its Width, and compare it to the GridViewColumn.Width.

A: 

I would think you have to look at a ControlTemplate trigger to solve this problem. Unfortunately ControlTemplate triggers always compare with a specific value, not less than or greater than. You can make it appear e.g. if the Width = 100, not Width < 100.

Zyphrax
+1  A: 

Ok, so why do it the hard XAML-only way? This works:

<TextBlock Text="{Binding Text}"
     IsMouseDirectlyOverChanged="TextBlock_IsMouseDirectlyOverChanged" >
     <TextBlock.ToolTip>
     <ToolTip Visibility="Collapsed">
         <TextBlock Text="{Binding Text}"></TextBlock>
     </ToolTip>
     </TextBlock.ToolTip>
</TextBlock>

in Control.xaml.cs:

private void TextBlock_IsMouseDirectlyOverChanged(object sender, e)
{
    bool isMouseOver = (bool)e.NewValue;
    if (!isMouseOver)
        return;
    TextBlock textBlock = (TextBlock)sender;
    bool needed = textBlock.ActualWidth > 
        (this.listView.View as GridView).Columns[2].ActualWidth;
    ((ToolTip)textBlock.ToolTip).Visibility = 
        needed ? Visibility.Visible : Visibility.Collapsed;
}
Martin Konicek
+5  A: 

I figured it out, the Tooltip has PlacementTarget property that specifies the UI element that has the Tooltip. In case anyone needs it:

<TextBlock Text="{Binding Text}">
    <TextBlock.ToolTip>
        <ToolTip 
             DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}" 
             Visibility="{Binding Converter={StaticResource toolVisConverter}">
             <TextBlock Text="{Binding Text}">  <!-- tooltip content -->
         </ToolTip>
    </TextBlock.ToolTip>
</TextBlock>

And then write a Converter that converts TextBlock to Visibility (based on TextBlock width).

Martin Konicek
A: 

Hi,

In my application, i have tried to implement the visibility of tooltip based on the textBlock's text length by using a converter. I too have coded using "PlacementTarget" as mentioned in the previous reply. I am facing some problems in displaying the toolTip text.

In the ToolTip, TextBlock's text binding is not working. If its binded with some hard coded strings, it works fine.

Vi