Показать WPF Tooltip, если необходимо
У меня есть TextBlock внутри элемента управления ограниченным размером. Если текст слишком длинный, чтобы вписаться в элемент управления, я бы хотел показать всплывающую подсказку с полным текстом. Это классическое поведение, которое вы наверняка знаете из многих приложений.
Я попытался использовать конвертер для преобразования ширины TextBlock в видимость подсказки.
<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>
Проблема заключается в том, что в конвертере:
public object Convert(object value, ...
'value' - элемент DataBound. Я бы хотел, чтобы "значение" было TextBlock, чтобы наблюдать за его шириной и сравнить его с GridViewColumn.Width.
Ответы
Ответ 1
Я понял, в подсказке есть свойство PlacementTarget, которое указывает элемент пользовательского интерфейса, который имеет всплывающую подсказку. Если кому-то это понадобится:
<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>
И затем напишите конвертер, который преобразует TextBlock в Visibility (на основе ширины TextBlock).
Ответ 2
Хорошо, так почему же это жесткий XAML-единственный способ? Это работает:
<TextBlock Text="{Binding Text}"
IsMouseDirectlyOverChanged="TextBlock_IsMouseDirectlyOverChanged" >
<TextBlock.ToolTip>
<ToolTip Visibility="Collapsed">
<TextBlock Text="{Binding Text}"></TextBlock>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
в 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;
}
Ответ 3
Я бы подумал, что вам нужно взглянуть на триггер ControlTemplate для решения этой проблемы. К сожалению, триггеры ControlTemplate всегда сравниваются с определенным значением, не меньше или больше. Вы можете сделать это, например. если ширина = 100, а не ширина < 100.