Show WPF Tooltip if needed

2019-01-21 17:16发布

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.

3条回答
The star\"
2楼-- · 2019-01-21 17:42

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).

查看更多
【Aperson】
3楼-- · 2019-01-21 17:47

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, DependencyPropertyChangedEventArgs 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;
}
查看更多
不美不萌又怎样
4楼-- · 2019-01-21 18:02

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.

查看更多
登录 后发表回答