WPF 中 TextBlock 设置TextTrimming 后,并根据需要自动显示 ToolTip

第一种方式:在 TextBlock 中使用附加属性

实现 TextBlockUtils 类,定义 AutoTooltip 附加属性

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
        }
    }
View Code

 xaml 代码中使用:

先在 xaml 首行添加 TextBlockUtils 类的命名空间:xmlns:util="clr-namespace:DriverEasyWPF.Utils”

然后将 Textblock 的 TextTrimming 属性设置为 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>
View Code

 

第二种方式,使用转换器来实现

实现转换器 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();
    }
}
View Code

在 App.xaml 中声明转换器:

<convert:TrimmedTextBlockVisibilityConverter x:Key="TrimmedTextBlockVisibilityConverter"/>
View Code

在 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>
View Code

注意:

使用附加属性的方式,如果在 ListBox 的 items 中 TextBlock 使用,如果 items 数量过大,界面可能会出现 1 秒左右的卡顿,才会显示最终效果。

使用转换器的方式就没有这个问题。

参考:

WPF 中 TEXTBLOCK 限制显示长度时,鼠标移入会自动出现 TOOLTIP

posted @ 2022-01-22 17:10  一菲聪天  阅读(974)  评论(0编辑  收藏  举报