WPF RichTextBox увеличить размер шрифта

Как видно из названия, моя цель - увеличить / уменьшить размер шрифта текущего выделения текста внутри RichTextBox.

Это может показаться тривиальным, и на самом деле это так - до тех пор, пока размер шрифта одинаков для всего текста в TextRange. Когда выделение содержит текст с разными размерами шрифта,

range.GetPropertyValue(TextElement.FontSizeProperty);

который я использую для получения предыдущего значения размера шрифта (необходимого для того, чтобы знать, какое значение установить) возвращает DependencyProperty.UnsetValue .

Проблема не только в этом, но и в том, что нет способа увеличить размер, здесь возникает только один способ явно установить его на заданное значение.

Я рассмотрел попытку анализа TextRange для поддиапазонов с различными значениями свойств, но это кажется действительно запутанным способом достижения чего-то, что должно быть тривиальным.

Как мне это сделать? Заранее спасибо.

4 ответа

Я думаю, что это должно сработать сейчас... как я прокомментировал в своем последнем посте, это заботится об автоматическом слиянии элементов , когда их текстовый размер становится одинаковым:

    private void sizeTextSel(int iVal)
    {
        TextSelection ts = _richTextBox.Selection;
        TextPointer tpStart = ts.Start;
        TextPointer tpEnd = ts.End;
        TextPointer tpRun = tpStart;

        int iSelLength = ts.Text.Length;
        int iStartRunLength;
        object fontSizeSelection;
        int iTotalSelected = 0, iSelect = 0,iNew=0;
        do
        {
            iStartRunLength = tpRun.GetTextRunLength(LogicalDirection.Forward);
            iSelect = iStartRunLength < iSelLength - iTotalSelected ? iStartRunLength : iSelLength - iTotalSelected;
            if (iStartRunLength > 0)
            {
                iSelect = iSelect == 0 ? 1 : iSelect;
                ts.Select(tpRun, tpRun.GetPositionAtOffset(iSelect, LogicalDirection.Forward));
                fontSizeSelection = ts.GetPropertyValue(TextElement.FontSizeProperty);
                if (fontSizeSelection != null)
                    ts.ApplyPropertyValue(TextElement.FontSizeProperty, (double)fontSizeSelection + iVal);
                iNew = tpRun.GetTextRunLength(LogicalDirection.Forward);
                if (iNew==0)
                    tpRun = tpRun.GetPositionAtOffset(iSelect + 1, LogicalDirection.Forward);
                else
                    tpRun = tpRun.GetPositionAtOffset(iSelect, LogicalDirection.Forward);
            }
            else
            {
                if (tpRun.Parent.GetType() == typeof(FlowDocument))
                    iSelect = 2;
                else
                    iSelect = 0;
                tpRun = tpRun.GetPositionAtOffset(1, LogicalDirection.Forward);
            }

            iTotalSelected += iSelect;

        } while (tpRun != null && iTotalSelected < iSelLength);

        ts.Select(tpStart, tpEnd);
    }

Я думаю, что любая реализация, если бы она существовала, в конечном итоге должна была бы делать то же самое, что вы предлагаете, поэтому ваши возможности ограничены:

Если вы обеспокоены тем, что это много операций, вы можете быть правы, и единственный концептуальный ярлык, о котором я могу подумать, это применить ScaleTransform. Это, конечно, только заставит его работать, и он не изменит свойства выделения.

Если вы обеспокоены тем, что в вашем пользовательском коде много помех, вы также правы, но я бы посоветовал скрыть это, создав собственный RichTextBox и самостоятельно реализовав IncrementSizeOfSelection и DecrementSizeOfSelection.

Думаю, необходимых операций не так уж много. Я пробовал это с несколькими различными размерами текста - этот пример работает, только когда выделенный текст заключен в элементы . Но должна быть возможность расширить код для различных элементов, таких как . Но я не знаю, как обрабатывать что-то вроде Bolded

    private void sizeTextSel(int iVal)
    {
        TextSelection ts = _richTextBox.Selection;
        TextPointer tpStart = ts.Start;
        TextPointer tpEnd = ts.End;
        TextPointer tpRun = tpStart;

        int iSelLength = tpStart.GetOffsetToPosition(tpEnd);
        int iStartRunLength;
        object fontSizeSelection;
        int iTotalSelected = 0,iSelect;

        do
        {                   
            iStartRunLength = tpRun.GetTextRunLength(LogicalDirection.Forward);
            iSelect = iStartRunLength < iSelLength - iTotalSelected ? iStartRunLength : iSelLength - iTotalSelected;
            ts.Select(tpRun, tpRun.GetPositionAtOffset(iSelect,LogicalDirection.Forward));
            fontSizeSelection = ts.GetPropertyValue(TextElement.FontSizeProperty);
            if (fontSizeSelection != null)
                ts.ApplyPropertyValue(TextElement.FontSizeProperty, (double)fontSizeSelection + iVal);

            tpRun = tpRun.GetPositionAtOffset(iSelect + 1);
            while (tpRun != null && tpRun.Parent.GetType() != typeof(Run))
            {
                tpRun = tpRun.GetPositionAtOffset(1);
                //iOffset +=1;
            }
            iTotalSelected += iSelect+1;

        } while (tpRun != null && iTotalSelected < iSelLength);

        ts.Select(tpStart, tpEnd);
    }

Получите TextRange с помощью выбора RichTextBox, который даст вам TextRange, и у вас будет двойное значение для размера шрифта. Попробуй это

 public void SetFontSizeForSelection(TextRange selection, double newFontSize)
        {
            if ((newFontSize - 0) < double.Epsilon)
                newFontSize = 1;
            selection.ApplyPropertyValue(TextElement.FontSizeProperty, newFontSize);
        }
Другие вопросы по тегам