English 中文(简体)
文本Range GetPosition AtOffset not behav as expected
原标题:TextRange GetPositionAtOffset not behaving as expected

我试图利用WPFRichTextEditor执行一个基本合成物。 为此,我要以不同颜色显示{}灰色。

这里应该将RichTextBox的内容分为不同的群体:

    List<Tag> SplitIntoParts(TextRange textRange, int level)
    {
        if (textRange==null||textRange.IsEmpty)
        {
            return new List<Tag>();
        }
        string text = textRange.Text;
        if (text.Length==0)
        {
            return new List<Tag>();
        }
        int startPos=-1, counter = 0;
        List<Tag> result=new List<Tag>();
        for (int i = 0; i < text.Length; i++)
        {
            if (text[i]== { )
            {
                if (counter==0)
                {
                    startPos = i;
                }
                counter++;
            }
            if (text[i]== } )
            {
                if (counter==1)
                {
                    Tag t = new Tag()
                                {
                                    StartPosition = textRange.Start.GetPositionAtOffset(startPos), 
                                    EndPosition = textRange.Start.GetPositionAtOffset(i+1), 
                                    Level = level,
                                    Word = text.Substring(startPos,i+1-startPos)
                                };
                    result.Add(t);
                    var tr=new TextRange(textRange.Start.GetPositionAtOffset(startPos + 1), textRange.Start.GetPositionAtOffset(i));
                    result.AddRange(SplitIntoParts(tr, level + 1));
                }
                counter--;
            }
        }
        if (counter>0)//some open branches still left
        {
            var i = text.Length;
            Tag t = new Tag()
            {
                StartPosition = textRange.Start.GetPositionAtOffset(startPos),
                EndPosition = textRange.End,
                Level = level,
                Word = text.Substring(startPos, i - startPos)
            };
            result.Add(t);
            result.AddRange(SplitIntoParts(new TextRange(textRange.Start.GetPositionAtOffset(startPos + 1), textRange.Start.GetPositionAtOffset(i - 1)), level + 1));
        }

        return result;
    }

在这项法典中,我找到了文本Range.Start.GetPositionAtOffset(启动) a) Po:

更不用说,该法典有以下几组:

{test|try}

并用以下代码选出:

var t=new Tag()
                                {
                                    StartPosition = textRange.Start.GetPositionAtOffset(startPos), 
                                    EndPosition = textRange.Start.GetPositionAtOffset(i+1), 
                                    Level = level,
                                    Word = text.Substring(startPos,i+1-startPos)
                                };

(e.g. t.Word== {test|try} )

当我试图以同样的休养方式通过时

var tr=new TextRange(textRange.Start.GetPositionAtOffset(startPos + 1), textRange.Start.GetPositionAtOffset(i));
result.AddRange(SplitIntoParts(tr, level + 1));

而不是“试验”

为什么我忘记了这一行为,我应如何处理这一问题?

最佳回答

。 只计算(可见)特性。 简言之,我最近也谈到同样的问题,因此我采取了一种方法,在规定的抵消中找到<代码>TextPointer(被抵消的只是表面特征)。 首先,这似乎很复杂,但实际上是:-。

作为一个参数,它需要一条线(从丰富的方框文本,如<代码>)。 RyTextBox.Document.Blocks.FirstBlocks. Inlines, 这两份文件仅载有其中第1段的斜线,如果是的话;第二个参数是被冲抵。

建议给出第三个参数,即<代码>TextPointer,注明内容的开始。 如果具体指明,起始位置从第一线确定,但如果没有条线,则会提出例外,以避免这种情况,将内容起始参数确定为<代码>。 RyTextBox.Document.ContentStart 。 该方法如下:

    /// <summary>
    /// Returns the position of the specified offset in the text specified by the inlines.
    /// </summary>
    /// <param name="inlines">The inlines which specifies the text.</param>
    /// <param name="offset">The offset within the text to get the position of.</param>
    /// <param name="contentStartPosition">The position where the content starts. If null, the position before the start of the first inline will be used. If null and there are no inlines, an exception is thrown.</param>
    /// <returns>A <see cref="TextPointer"/> indicating the position of the specified offset.</returns>
    public static TextPointer GetPositionAtOffset(this InlineCollection inlines, int offset, TextPointer contentStartPosition = null)
    {
        if (inlines == null)
            throw new ArgumentNullException(nameof(inlines));
        if (!inlines.Any() && contentStartPosition == null)//if no inlines, can t determine start of content
            throw new ArgumentException("A content start position has to be specified if the inlines collection is empty.", nameof(contentStartPosition));

        if (contentStartPosition == null)
            contentStartPosition = inlines.First().ContentStart.DocumentStart;//if no content start specified, gets it
        int offsetWithInlineBorders = 0;//collects the value of offset (with inline borders)
        foreach (var inline in inlines)
        {
            int inlineLength = (inline as Run)?.Text.Length ?? (inline is LineBreak ? 1 : 0);//gets the length of the inline (length of a Run is the lengts of its text, length of a LineBreak is 1, other types are ignored)

            if (inlineLength < offset)//if position specified by the offset is beyond this inline...
                offsetWithInlineBorders += inlineLength + 2;//...then the whole length is added with the two borders
            else if (inlineLength == offset)//if position specified by the offset is at the end of this inline...
                offsetWithInlineBorders += inlineLength + 1;//...then the whole length is added with only the opening border
            else //inlineLength > value, if the position specified by the offset is within this inline
            {
                offsetWithInlineBorders += offset + 1;//...then adds the remaining length (the offset itself), plus the opening border
                break;//the inlines beyond are not needed
            }
            offset -= inlineLength;//substracts the added inline length
        }

        return contentStartPosition.GetPositionAtOffset(
            Math.Min(Math.Max(offsetWithInlineBorders, 0), contentStartPosition.GetOffsetToPosition(contentStartPosition.DocumentEnd)));//if the value is not within the boundaries of the text, returns the start or the end of the text
    }

亲爱

问题回答

GetPositionAtOffset counts symbols, which may be more than text insertion positions. See MSDN:

Returns a TextPointer to the position indicated by the specified offset, in symbols, from the beginning of the current TextPointer.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签