1

我正在尝试使用 silverlight 5 Richtextbox 创建用户控件。我需要能够插入“内联 ui”,但不知道如何获取当前光标位置。

我像这样触发我的代码:

this.GetAbsolutePos(this.richText.Selection.Start);

这种方法的核心在这里:

private int GetAbsolutePos(TextPointer textPointer)
{
   int index = 0;
   TextPointer pos = this.richText.ContentStart;
   while (pos.CompareTo(textPointer) != 0)
   {
      if (pos.IsAtInsertionPosition)
      {
          index++;
      }

      pos = pos.GetNextInsertionPosition(LogicalDirection.Forward);
   }
   return index;
}

给定富文本框控件中的以下文本....

空控制

如果光标在第一行的 5 和 6 之间,则上述函数正确返回 5。但随着光标进一步进入文本,位置变得更加不准确。即第二行的 5 和 6 之间返回 16,第三行返回 27。

当我在这些位置插入内联元素时,这也变得更加困难,然后将其视为“符号”并进一步导致计数出错。

此图显示了当我在每行的 5 和 6 之间“插入”内联 ui 时发生的情况。 带 3 个内联

只是为了完整起见,这里是来自richtext.Xaml 的 Xaml(我已经从 Section/Paragraph 元素中删除了所有额外的属性以使其更清晰)

<Section>
   <Paragraph>
       <Run>1234567890</Run>
       <LineBreak />
       <Run>1234567890</Run>
       <LineBreak />
       <Run>1234567890</Run>
   </Paragraph>
</Section> 

基于this page MSDN Silverlight TextPointer Class的备注

符号 - 对于 TextPointer 操作,以下任何一项都被视为符号:

  • TextElement 元素的开始或结束标记。

  • 包含在 InlineUIContainer 中的 UIElement 元素。请注意,UIElement 始终被计为一个符号。UIElement 包含的任何其他内容或元素均不被视为符号。

  • 文本 Run 元素内的每个 16 位 Unicode 字符。

我想我需要“知道”我目前使用的是哪种“符号”,但无法弄清楚如何。

看起来应该很容易,但使用 TextPointers 似乎很不直观。我有一个想法来解析 Xaml 以找到光标位置,但这似乎是一个真正的 hack。

任何帮助,将不胜感激。

谢谢

4

2 回答 2

0

最后,我们只是通过文本点之前的 SubstituteEdits(我们的 UIElement 表示)的数量手动调整索引。它仍然不稳定,我们的控制还有其他问题,但目前已经足够好了。

干杯

蒂姆

    private int GetAbsolutePos(SubstituteEdit newSub)
    {
        int index = 0;
        TextPointer textPointer = this.richText.Selection.Start;
        TextPointer caretWhere = this.richText.ContentStart;

        while (true)
        {
            caretWhere = caretWhere.GetNextInsertionPosition(LogicalDirection.Forward);
            if (caretWhere == null || caretWhere.CompareTo(textPointer) == 0)
            {
                break;
            }

            index++;
        }

        foreach (SubstituteEdit sub in this.Substitutes)
        {
            if (sub.Position < index && sub != newSub)
            {
                index--;
            }
        }

        return index;
    }
于 2013-04-05T08:42:10.623 回答
0

我不确定这是否会有所帮助,但我最终让用户插入选择的位置而不是插入符号位置,它似乎运作良好。这是我的一些代码:

InlineUIContainer MyUI = new InlineUIContainer();
TextBlock tblx = new TextBlock() { Text = addedItem.Title, FontWeight = FontWeights.Bold };
MyUI.Child = tblx;
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(MyUI);
rtb.Selection.Insert(myParagraph);
于 2014-10-09T17:51:38.683 回答