第一种方案:(通过附加属性来实现)
附加属性的代码 TextBlockUtils 类:
public class TextBlockUtils
{
/// <summary>
/// Gets the value of the AutoTooltipProperty dependency property
/// </summary>
public static bool GetAutoTooltip(DependencyObject obj)
{
return (bool)obj.GetValue(AutoTooltipProperty);
}
/// <summary>
/// Sets the value of the AutoTooltipProperty dependency property
/// </summary>
public static void SetAutoTooltip(DependencyObject obj, bool value)
{
obj.SetValue(AutoTooltipProperty, value);
}
/// <summary>
/// Identified the attached AutoTooltip property. When true, this will set the TextBlock TextTrimming
/// property to WordEllipsis, and display a tooltip with the full text whenever the text is trimmed.
/// </summary>
public static readonly DependencyProperty AutoTooltipProperty = DependencyProperty.RegisterAttached("AutoTooltip",
typeof(bool), typeof(TextBlockUtils), new PropertyMetadata(false, OnAutoTooltipPropertyChanged));
private static void OnAutoTooltipPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBlock textBlock = d as TextBlock;
if (textBlock == null)
return;
if (e.NewValue.Equals(true))
{
textBlock.TextTrimming = TextTrimming.WordEllipsis;
ComputeAutoTooltip(textBlock);
textBlock.SizeChanged += TextBlock_SizeChanged;
}
else
{
textBlock.SizeChanged -= TextBlock_SizeChanged;
}
}
private static void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
{
TextBlock textBlock = sender as TextBlock;
ComputeAutoTooltip(textBlock);
}
/// <summary>
/// Assigns the ToolTip for the given TextBlock based on whether the text is trimmed
/// </summary>
private static void ComputeAutoTooltip(TextBlock textBlock)
{
#if !Silverlight
textBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
var width = textBlock.DesiredSize.Width;
if (textBlock.ActualWidth < width)
{
ToolTipService.SetToolTip(textBlock, textBlock.Text);
}
else
{
ToolTipService.SetToolTip(textBlock, null);
}
#else
FrameworkElement parentElement = VisualTreeHelper.GetParent(textBlock) as FrameworkElement;
if (parentElement != null)
{
if (textBlock.ActualWidth > parentElement.ActualWidth)
{
ToolTipService.SetToolTip(textBlock, textBlock.Text);
}
else
{
ToolTipService.SetToolTip(textBlock, null);
}
}
#endif
}
}
xaml 代码:
在 xaml 首行添加 TextBlockUtils 类的命名空间:xmlns:util=”clr-namespace:DriverEasyWPF.Utils”
将 Textbloc 的 TextTrimming 属性设置为 true;
使用附加属性 util:TextBlockUtils.AutoTooltip = “True”
<Grid MaxWidth="200">
<TextBlock Text="A few weeks ago, I blogged about a Silverlight solution for automatically adding tooltips when a TextBlock Text is trimmed and renders an ellipsis. I found a decent looking WPF solutions on the web and linked it in my article" VerticalAlignment="Center" TextTrimming="WordEllipsis" util:TextBlockUtils.AutoTooltip="True"/>
</Grid>
第二种方案:(通过转换器来实现)
转换器 TrimmedTextBlockVisibilityConverter 类:
public class TrimmedTextBlockVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || value == DependencyProperty.UnsetValue) 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();
}
}
在 App.xaml 中声明转换器:
<convert:TrimmedTextBlockVisibilityConverter x:Key="TrimmedTextBlockVisibilityConverter"/>
在 xaml 中使用:
将 Textblock 的 TextTrimming 属性设置为 true;
<Grid MaxWidth="395">
<TextBlock Text="A few weeks ago, I blogged about a Silverlight solution for automatically adding tooltips when a TextBlock Text is trimmed and renders an ellipsis. I found a decent looking WPF solutions on the web and linked it in my article" VerticalAlignment="Center" TextTrimming="WordEllipsis">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="#333"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#22acff"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
<TextBlock.ToolTip>
<ToolTip Visibility="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget, Converter={StaticResource TrimmedTextBlockVisibilityConverter}}" Content="A few weeks ago, I blogged about a Silverlight solution for automatically adding tooltips when a TextBlock Text is trimmed and renders an ellipsis. I found a decent looking WPF solutions on the web and linked it in my article">
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</Grid>
注意:
使用附加属性的方式,如果在 ListBox 的 items 中 TextBlock 使用,如果 items 数量过大,界面可能会出现 1 秒左右的卡顿,才会显示最终效果。
使用转换器的方式就没有这个问题。
参考:
Automatically Showing ToolTips on a Trimmed TextBlock (Silverlight + WPF)