TextBlock 重写,当文本过长时,自动截断文本并出现Tooltip

2023-05-25,,

如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
using System.Globalization; namespace XXXX
{
public class TooltipTextBlock : TextBlock
{
static TooltipTextBlock()
{
OneLineHeightProperty =
DependencyProperty.Register(
"OneLineHeight",
typeof(double),
typeof(TooltipTextBlock),
new FrameworkPropertyMetadata((double))
);
}
protected override void OnToolTipOpening(ToolTipEventArgs e)
{
if (TextTrimming != TextTrimming.None)
{
e.Handled = !IsTextTrimmed();
}
} private bool IsTextTrimmed()
{
var typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
var formattedText = new FormattedText(Text, CultureInfo.CurrentCulture, FlowDirection, typeface, FontSize, Foreground);
double lineHeight = OneLineHeight;//formattedText.Height;
double totalWidth = formattedText.Width; int lines = (int)Math.Ceiling(totalWidth / ActualWidth); return (lines * lineHeight > MaxHeight);
}
public double OneLineHeight
{
get { return (double)GetValue(OneLineHeightProperty); }
set { SetValue(OneLineHeightProperty, value); }
} public static readonly DependencyProperty OneLineHeightProperty;
}
}

使用:

            TooltipTextBlock tb = new TooltipTextBlock();
tb.Margin = new Thickness(, , , );
tb.Width = ;
tb.MaxHeight = ;
tb.TextAlignment = TextAlignment.Center;
tb.Style = (Style)Utils.CommonFunctions.LoadResource("CardBody_TextStyle");
tb.TextTrimming = TextTrimming.WordEllipsis;
tb.TextWrapping = TextWrapping.Wrap;
tb.OneLineHeight = ;
ToolTip tt = new ToolTip() { Content = des, };
tb.ToolTip = tt;

或:

xmlns:local="clr-namespace:Test"
<local:TooltipTextBlock Text="This is some text lafsdk jflklakjsd " TextWrapping="Wrap"
TextTrimming="WordEllipsis"
ToolTip="{Binding Text,RelativeSource={RelativeSource Self}}"
MaxWidth="" Height="" MaxHeight="" Background="Gray" OneLineHeight=""/>

新方法:

<TextBlock Text="Demo" ui:TextBlockAutoToolTip.Enabled="True"/>
var textBlock = new TextBlock { Text = "Demo" };
TextBlockAutoToolTip.SetEnabled(textBlock, true);
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media; namespace Unclassified.UI
{
/// <summary>
/// Shows a ToolTip over a TextBlock when its text is trimmed.
/// </summary>
public class TextBlockAutoToolTip
{
/// <summary>
/// The Enabled attached property.
/// </summary>
public static readonly DependencyProperty EnabledProperty = DependencyProperty.RegisterAttached(
"Enabled",
typeof(bool),
typeof(TextBlockAutoToolTip),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnAutoToolTipEnabledChanged))); /// <summary>
/// Sets the Enabled attached property on a TextBlock control.
/// </summary>
/// <param name="dependencyObject">The TextBlock control.</param>
/// <param name="enabled">The value.</param>
public static void SetEnabled(DependencyObject dependencyObject, bool enabled)
{
dependencyObject.SetValue(EnabledProperty, enabled);
} private static readonly TrimmedTextBlockVisibilityConverter ttbvc = new TrimmedTextBlockVisibilityConverter(); private static void OnAutoToolTipEnabledChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
TextBlock textBlock = dependencyObject as TextBlock;
if (textBlock != null)
{
bool enabled = (bool)args.NewValue;
if (enabled)
{
var toolTip = new ToolTip
{
Placement = System.Windows.Controls.Primitives.PlacementMode.Relative,
VerticalOffset = -,
HorizontalOffset = -,
Padding = new Thickness(, , , ),
Background = Brushes.White
};
toolTip.SetBinding(UIElement.VisibilityProperty, new System.Windows.Data.Binding
{
RelativeSource = new System.Windows.Data.RelativeSource(System.Windows.Data.RelativeSourceMode.Self),
Path = new PropertyPath("PlacementTarget"),
Converter = ttbvc
});
toolTip.SetBinding(ContentControl.ContentProperty, new System.Windows.Data.Binding
{
RelativeSource = new System.Windows.Data.RelativeSource(System.Windows.Data.RelativeSourceMode.Self),
Path = new PropertyPath("PlacementTarget.Text")
});
toolTip.SetBinding(Control.ForegroundProperty, new System.Windows.Data.Binding
{
RelativeSource = new System.Windows.Data.RelativeSource(System.Windows.Data.RelativeSourceMode.Self),
Path = new PropertyPath("PlacementTarget.Foreground")
});
textBlock.ToolTip = toolTip;
textBlock.TextTrimming = TextTrimming.CharacterEllipsis;
}
}
} private class TrimmedTextBlockVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var textBlock = value as TextBlock;
if (textBlock == null)
return Visibility.Collapsed; Typeface typeface = new Typeface(
textBlock.FontFamily,
textBlock.FontStyle,
textBlock.FontWeight,
textBlock.FontStretch); // FormattedText is used to measure the whole width of the text held up by TextBlock container
FormattedText formattedText = new FormattedText(
textBlock.Text,
System.Threading.Thread.CurrentThread.CurrentCulture,
textBlock.FlowDirection,
typeface,
textBlock.FontSize,
textBlock.Foreground); formattedText.MaxTextWidth = textBlock.ActualWidth; // When the maximum text width of the FormattedText instance is set to the actual
// width of the textBlock, if the textBlock is being trimmed to fit then the formatted
// text will report a larger height than the textBlock. Should work whether the
// textBlock is single or multi-line.
// The width check detects if any single line is too long to fit within the text area,
// this can only happen if there is a long span of text with no spaces.
bool isTrimmed = formattedText.Height > textBlock.ActualHeight ||
formattedText.MinWidth > formattedText.MaxTextWidth; return isTrimmed ? Visibility.Visible : Visibility.Collapsed;
} public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
}

TextBlock 重写,当文本过长时,自动截断文本并出现Tooltip的相关教程结束。

《TextBlock 重写,当文本过长时,自动截断文本并出现Tooltip.doc》

下载本文的Word格式文档,以方便收藏与打印。