Windows application determines if TextBlock is clipped

I have a GridItem with a fixed height / width.

It contains a text block with a maximum set of lines.

How can I determine if this text has been trimmed? I want to add special functionality if it is cropped.

+6
source share
2 answers

As a result, we created a static function

// Ensure block does not have MAXLINES or text trimming set prior to checking public static bool IsTruncated(TextBlock block, int maxLines) { if (block == null) { throw new ArgumentNullException("block"); } //the cut-off height is the height at which text will be cut off in the UI var cutOffHeight = maxLines * block.LineHeight; //determine whether the actual height of the TextBlock is greater than the cut-off height return block.ActualHeight > cutOffHeight; } 

The trick is to make sure that Maxlines and text trimming are NOT set to Textblock before running this function. After this function returns, that is, when Maxlines are installed. In my case, I just saved the returned Boolean in the containing object, so I knew it was longer. Then I set maxlines and another button to see the advanced content based on this Boolean.

+1
source

The old way is when Text Print is set to None

To find out if a TextBlock is TextBlock , we can subscribe to its SizeChanged event and compare its ActualWidth with the MaxWidth you MaxWidth . To get ActualWidth for the TextBlock to the right , we need to leave the default TextTrimming value (i.e. TextTrimming.None ) and set it to trim after the width has passed.

New way - when installing TextWrapping on Wrap

Now that I know, because TextWrapping set to Wrap and it is assumed that VirticalAlignment not specified (by default Stretch ), Width will always remain the same. We only need to track the SizeChanged event when the actual height of the TextBlock exceeds the height of the parent element.

Let Behavior be used to encapsulate all of the above logic. It is worth mentioning here that a static helper class with a bunch of attached properties or a new control that inherits from TextBlock can do the same; but as a big fan of Blend, I prefer to use the Behaviors whenever possible.

Behavior

 public class TextBlockAutoTrimBehavior : DependencyObject, IBehavior { public bool IsTrimmed { get { return (bool)GetValue(IsTrimmedProperty); } set { SetValue(IsTrimmedProperty, value); } } public static readonly DependencyProperty IsTrimmedProperty = DependencyProperty.Register("IsTrimmed", typeof(bool), typeof(TextBlockAutoTrimBehavior), new PropertyMetadata(false)); public DependencyObject AssociatedObject { get; set; } public void Attach(DependencyObject associatedObject) { this.AssociatedObject = associatedObject; var textBlock = (TextBlock)this.AssociatedObject; // subscribe to the SizeChanged event so we will know when the Width of the TextBlock goes over the MaxWidth textBlock.SizeChanged += TextBlock_SizeChanged; } private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e) { // ignore the first time height change if (e.PreviousSize.Height != 0) { var textBlock = (TextBlock)sender; // notify the IsTrimmed dp so your viewmodel property will be notified via data binding this.IsTrimmed = true; // unsubscribe the event as we don't need it anymore textBlock.SizeChanged -= TextBlock_SizeChanged; // then we trim the TextBlock textBlock.TextTrimming = TextTrimming.WordEllipsis; } } public void Detach() { var textBlock = (TextBlock)this.AssociatedObject; textBlock.SizeChanged += TextBlock_SizeChanged; } } 

Xaml

 <Grid HorizontalAlignment="Center" Height="73" VerticalAlignment="Center" Width="200" Background="#FFD2A6A6" Margin="628,329,538,366"> <TextBlock x:Name="MyTextBlock" TextWrapping="Wrap" Text="test" FontSize="29.333"> <Interactivity:Interaction.Behaviors> <local:TextBlockAutoTrimBehavior IsTrimmed="{Binding IsTrimmedInVm}" /> </Interactivity:Interaction.Behaviors> </TextBlock> </Grid> 

Note that Behavior provides the IsTrimmed dependency IsTrimmed , you can bind it to a property in your viewmodel (i.e., IsTrimmedInVm in this case).

PS There is no FormattedText function in FormattedText , otherwise the implementation may be slightly different.

+5
source

Source: https://habr.com/ru/post/974569/


All Articles