Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF流程文档“变更案例”功能_C#_Wpf_Flowdocument - Fatal编程技术网

C# WPF流程文档“变更案例”功能

C# WPF流程文档“变更案例”功能,c#,wpf,flowdocument,C#,Wpf,Flowdocument,我正在用Shift+F3为我的RichTextBox实现一个类似word的变更案例功能。它所做的只是在下->上->标题大小写之间切换,这在我获得所需字符串的访问权限后非常简单 我的问题是,如何在不丢失任何嵌入元素的情况下更改和查找flowdocument中的字符串丢失格式不是字符串中可能包含的问题。 与word相同,我需要在两种情况下使用此功能: 1鼠标选择文本。我简单地试了一下 this.Selection.Text = newText; 但那当然失去了我的内在元素 2插入符号位置前的最后一

我正在用Shift+F3为我的RichTextBox实现一个类似word的变更案例功能。它所做的只是在下->上->标题大小写之间切换,这在我获得所需字符串的访问权限后非常简单

我的问题是,如何在不丢失任何嵌入元素的情况下更改和查找flowdocument中的字符串丢失格式不是字符串中可能包含的问题。 与word相同,我需要在两种情况下使用此功能:

1鼠标选择文本。我简单地试了一下

this.Selection.Text = newText;
但那当然失去了我的内在元素

2插入符号位置前的最后一个单词。任何非文本元素都是单词分隔符,但可以是一个单词

"He<weird formatting begin>ll<weird formatting end>o".
解决方案

通过这种方式,它模仿了MS WORD Shift+F3的行为。在极少数情况下出现的唯一问题是carret被移动到单词的开头,而不是保持它的位置。我想编辑commands.MoveLeftByWord.Executenull之后需要短暂的睡眠;我会解决这个问题,但这将是一个肮脏的黑客,我正试图找到一个更好的解决办法

private void ChangeCase()
    {
        try
        {
            TextPointer start;
            TextPointer end;
            FindSelectedRange(out start, out end);
            List<TextRange> textToChange = SplitToTextRanges(start, end);
            ChangeCaseToAllRanges(textToChange);
        }
        catch (Exception ex)
        {
            mLog.Error("Change case error", ex);
        }


    }

    private void FindSelectedRange(out TextPointer start, out TextPointer end)
    {
        if (!this.Selection.IsEmpty)
        {
            start = this.Selection.Start;
            end = this.Selection.End;
        }
        else
        {
            end = this.CaretPosition;
            EditingCommands.MoveLeftByWord.Execute(null, this);
            start = this.CaretPosition;
            this.CaretPosition = end;

        }
    }

    private static List<TextRange> SplitToTextRanges(TextPointer start, TextPointer end)
    {
        List<TextRange> textToChange = new List<TextRange>();
        var previousPointer = start;
        for (var pointer = start; pointer.CompareTo(end) <= 0; pointer = pointer.GetPositionAtOffset(1, LogicalDirection.Forward))
        {
            var contextAfter = pointer.GetPointerContext(LogicalDirection.Forward);
            var contextBefore = pointer.GetPointerContext(LogicalDirection.Backward);
            if (contextBefore != TextPointerContext.Text && contextAfter == TextPointerContext.Text)
            {
                previousPointer = pointer;
            }
            if (contextBefore == TextPointerContext.Text &&  contextAfter != TextPointerContext.Text && previousPointer != pointer)
            {
                textToChange.Add(new TextRange(previousPointer, pointer));
                previousPointer = null;
            }
        }
        textToChange.Add(new TextRange(previousPointer ?? end, end));
        return textToChange;
    }

    private void ChangeCaseToAllRanges(List<TextRange> textToChange)
    {
        var textInfo = (mCasingCulture ?? CultureInfo.CurrentUICulture).TextInfo;
        var allText = String.Join(" ", textToChange.Select(x => x.Text).Where(x => !string.IsNullOrWhiteSpace(x)));
        Func<string, string> caseChanger = GetConvertorToNextState(textInfo, allText);
        foreach (var range in textToChange)
        {
            if (!range.IsEmpty && !string.IsNullOrWhiteSpace(range.Text))
            {
                range.Text = caseChanger(range.Text);
            }
        }
    }

    private static Func<string, string> GetConvertorToNextState(TextInfo textInfo, string allText)
    {
        Func<string, string> caseChanger;
        if (textInfo.ToLower(allText) == allText)
        {
            caseChanger = (text) => textInfo.ToTitleCase(text);
        }
        else if (textInfo.ToTitleCase(textInfo.ToLower(allText)) == allText)
        {
            caseChanger = (text) => textInfo.ToUpper(text);
        }
        else
        {
            caseChanger = (text) => textInfo.ToLower(text);
        }
        return caseChanger;
    }