CustomRichTextBox StrikeThrough TextDecoration

Я хочу добавить декоративную кнопку TextDecorations.Strikethrough к своему пользовательскому RichTextBox. Я использую приведенный ниже код для добавления и удаления TextDecoration. Дело в том, что я получаю InvalidCastException: Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.Windows.TextDecorationCollection'., когда выбираю диапазон, больший, чем тот, который зачеркнут, и нажимаю " кнопку «Перечеркнуть».

Мой код

private void StrikeOutButton_Click(object sender, RoutedEventArgs e)
    {
        TextRange range = new TextRange(this.MyRichTextBox.Selection.Start,
                                      this.MyRichTextBox.Selection.End);

        TextDecorationCollection tdc =
            (TextDecorationCollection)this.MyRichTextBox.
                 Selection.GetPropertyValue(Inline.TextDecorationsProperty);
        /*
        if (tdc == null || !tdc.Equals(TextDecorations.Strikethrough))
        {
            tdc = TextDecorations.Strikethrough;
        }
        else
        {
            tdc = new TextDecorationCollection();
        }
         * */
        if (tdc == null || !tdc.Contains(TextDecorations.Strikethrough[0]))
        {
            tdc = TextDecorations.Strikethrough;
        }
        else
        {
            tdc = new TextDecorationCollection();
        }

        range.ApplyPropertyValue(Inline.TextDecorationsProperty, tdc);
    }

код комментария тоже не работает.

Я собирался опубликовать ExceptionDetails, но я думаю, что это очень ясно.

Может ли кто-нибудь предоставить мне обходной путь?


person Zoti    schedule 19.06.2015    source источник


Ответы (1)


Проблема в том, что вы получите DependencyProperty.UnsetValue, если не весь ваш текст украшен зачеркиванием или нет.

Таким образом, вы можете проверить наличие DependencyProperty.UnsetValue и в этом случае просто применить зачеркивание.

Я сделал короткий тест, и это решение работает для меня:

private void StrikeOutButton_Click(object sender, RoutedEventArgs e)
    {
        TextRange textRange = new TextRange(TextBox.Selection.Start, TextBox.Selection.End);
        var currentTextDecoration = textRange.GetPropertyValue(Inline.TextDecorationsProperty);

        TextDecorationCollection newTextDecoration;

        if (currentTextDecoration != DependencyProperty.UnsetValue)
            newTextDecoration = ((TextDecorationCollection)currentTextDecoration == TextDecorations.Strikethrough) ? new TextDecorationCollection() : TextDecorations.Strikethrough;
        else
            newTextDecoration = TextDecorations.Strikethrough;

        textRange.ApplyPropertyValue(Inline.TextDecorationsProperty, newTextDecoration);
    }
person Carpi    schedule 14.10.2015
comment
оно работает. я использовал что-то подобное, когда исправил это. по какой-то причине ссылка, которую я предоставил в качестве ответа, была удалена. - person Zoti; 14.10.2015