Отработка Eyjafj ... независимо от идеи, я пришел к рабочему, в основном декларативному решению, которое, по крайней мере, не требует специального элемента управления.Первое препятствие, которое нужно преодолеть, это добраться до TextBlock.Поскольку подсказка отображается за пределами визуального дерева, вы не можете использовать привязку RelativeSource или ElementName для доступа к TextBlock.К счастью, класс ToolTip предоставляет ссылку на связанный элемент через свойство PlacementTarget.Таким образом, вы можете привязать свойство Visibility ToolTip к самой ToolTip и использовать его свойство PlacementTarget для доступа к свойствам TextBlock:
<ToolTip Visibility="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget, Converter={StaticResource trimmedVisibilityConverter}}">
Следующий шаг - использование конвертера для просмотра TextBlock, с которым мы связанычтобы определить, должна ли подсказка быть видимой или нет.Вы можете сделать это, используя ActualWidth и DesiredSize.ActualWidth - именно то, на что это похоже;ширина вашего TextBlock была отображена на экране.DesiredSize - это ширина, которую предпочитает ваш TextBlock.Единственная проблема заключается в том, что DesiredSize, похоже, принимает во внимание TextTrimming и не дает ширину полного необрезанного текста.Чтобы решить эту проблему, мы можем повторно вызвать метод Measure, передав бесконечность Double.Positive, чтобы по сути спросить, насколько широким будет TextBlock, если бы его ширина не была ограничена.Это обновляет свойство DesiredSize, а затем мы можем сделать сравнение:
textBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
if (((FrameworkElement)value).ActualWidth < ((FrameworkElement)value).DesiredSize.Width)
return Visibility.Visible;
Этот подход фактически иллюстрируется здесь как прикрепленное поведение , если вы хотите применить его автоматически к TextBlocks или неЯ не хочу тратить ресурсы на создание всплывающих подсказок, которые всегда будут невидимы.Вот полный код для моего примера:
Конвертер:
public class TrimmedTextBlockVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return Visibility.Collapsed;
FrameworkElement textBlock = (FrameworkElement)value;
textBlock.Measure(new System.Windows.Size(Double.PositiveInfinity, Double.PositiveInfinity));
if (((FrameworkElement)value).ActualWidth < ((FrameworkElement)value).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();
}
}
XAML:
<UserControl.Resources>
<local:TrimmedTextBlockVisibilityConverter x:Key="trimmedVisibilityConverter" />
</UserControl.Resources>
....
<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding SomeTextProperty}">
<TextBlock.ToolTip>
<ToolTip Visibility="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget, Converter={StaticResource trimmedVisibilityConverter}}">
<ToolTip.Content>
<TextBlock Text="{Binding SomeTextProperty}"/>
</ToolTip.Content>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>