Exemplo n.º 1
0
        private static void TrimText(TextBlock textBlock,
                                     string text,
                                     double size,
                                     ICollection <string> segments,
                                     double epsilon,
                                     bool reversed)
        {
            while (true)
            {
                if (text.Length == 1)
                {
                    var textSize = TextBlockTrimmer.MeasureString(textBlock, text);
                    if (textSize <= size)
                    {
                        segments.Add(text);
                    }

                    return;
                }

                var halfLength    = Math.Max(1, text.Length / 2);
                var firstHalf     = reversed ? text.Substring(halfLength) : text.Substring(0, halfLength);
                var remainingSize = size - TextBlockTrimmer.MeasureString(textBlock, firstHalf);
                if (remainingSize < 0)
                {
                    // only one character and it's still too large for the room, skip it
                    if (firstHalf.Length == 1)
                    {
                        return;
                    }

                    text = firstHalf;
                    continue;
                }

                segments.Add(firstHalf);

                if (remainingSize > epsilon)
                {
                    var secondHalf = reversed ? text.Substring(0, halfLength) : text.Substring(halfLength);
                    text = secondHalf;
                    size = remainingSize;
                    continue;
                }

                break;
            }
        }
Exemplo n.º 2
0
        private void TrimText()
        {
            var textBlock = (TextBlock)this.Content;

            if (textBlock == null)
            {
                return;
            }

            if (DesignerProperties.GetIsInDesignMode(textBlock))
            {
                return;
            }

            var freeSize = _constraint.Width
                           - this.Padding.Left
                           - this.Padding.Right
                           - textBlock.Margin.Left
                           - textBlock.Margin.Right;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (freeSize <= 0)
            {
                return;
            }

            using (this.BlockTextChangedEvent())
            {
                // this actually sets textBlock's text back to its original value
                var desiredSize = TextBlockTrimmer.MeasureString(textBlock, _originalText);

                if (desiredSize <= freeSize)
                {
                    return;
                }

                var ellipsisSize = TextBlockTrimmer.MeasureString(textBlock, ELLIPSIS);
                freeSize -= ellipsisSize;
                var epsilon = ellipsisSize / 3;

                if (freeSize < epsilon)
                {
                    textBlock.Text = _originalText;
                    return;
                }

                var segments = new List <string>();

                var builder = new StringBuilder();

                switch (this.EllipsisPosition)
                {
                case EllipsisPosition.End:
                    TextBlockTrimmer.TrimText(textBlock, _originalText, freeSize, segments, epsilon, false);
                    foreach (var segment in segments)
                    {
                        builder.Append(segment);
                    }
                    builder.Append(ELLIPSIS);
                    break;

                case EllipsisPosition.Start:
                    TextBlockTrimmer.TrimText(textBlock, _originalText, freeSize, segments, epsilon, true);
                    builder.Append(ELLIPSIS);
                    foreach (var segment in ((IEnumerable <string>)segments).Reverse())
                    {
                        builder.Append(segment);
                    }
                    break;

                case EllipsisPosition.Middle:
                    var textLength = _originalText.Length / 2;
                    var firstHalf  = _originalText.Substring(0, textLength);
                    var secondHalf = _originalText.Substring(textLength);

                    freeSize /= 2;

                    TextBlockTrimmer.TrimText(textBlock, firstHalf, freeSize, segments, epsilon, false);
                    foreach (var segment in segments)
                    {
                        builder.Append(segment);
                    }
                    builder.Append(ELLIPSIS);

                    segments.Clear();

                    TextBlockTrimmer.TrimText(textBlock, secondHalf, freeSize, segments, epsilon, true);
                    foreach (var segment in ((IEnumerable <string>)segments).Reverse())
                    {
                        builder.Append(segment);
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }

                textBlock.Text = builder.ToString();
            }
        }