【问题标题】:RichTextBox and Inserting at Caret PositionsRichTextBox 并在插入符号位置插入
【发布时间】:2010-02-08 19:24:48
【问题描述】:

这里是交易:我有一个 RichTextBox 控件,它工作正常。问题是有一个“插入当前日期时间”按钮,它将当前日期时间添加/注入到 RichTextBox 中。用户可以在插入符号指向的任何地方输入日期时间。这涉及复杂的字符串操作和东西。

关于如何获得当前插入符号位置的任何想法。每当我得到 RichTextBox.CaretPositon 时,它似乎都指向 RichTextBox 的开头,而不是实际插入符号所在的位置。

更新 1:

日期时间按钮点击代码:

 private void DateTimeStampButton_Click(object sender, RoutedEventArgs e)
        {
            //TextRange tr = new TextRange(textBox.Selection.Start, textBox.Selection.End);
            var tr = new TextRange(textBox.Document.ContentStart, textBox.Document.ContentEnd);

            if(tr.Text.Length == 2)
            {
                if(tr.Text == "\r\n")
                {
                    tr.Text = tr.Text.TrimStart(new[] { '\r', '\n' }); 
                }
            }

            textBox.CaretPosition.InsertTextInRun(DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ":  ");

            DateTimeStampButton.Focusable = false;
        }

 private void SharpRichTextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            SetValue(TextProperty, Text);

            var binding = BindingOperations.GetBinding(this, TextProperty);

            if (binding == null) return;

            if (binding.UpdateSourceTrigger == UpdateSourceTrigger.Default || binding.UpdateSourceTrigger == UpdateSourceTrigger.LostFocus)
            {
                // if (TextProperty != null) BindingOperations.GetBindingExpression(this, TextProperty).UpdateSource();
            }
        }






public string Text
        {
            get
            {
                var newValue = new TextRange(Document.ContentStart, Document.ContentEnd).Text.RemoveNewLineAndReturn(); 
                return newValue; 
            }
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    SetValue(TextProperty, value.RemoveNewLineAndReturn());
                    Document.Blocks.Clear(); 
                    Document.Blocks.Add(new Paragraph(new Run(value))); 
                    OnPropertyChanged("Text"); 
                }
            }
        }

更新 2:

原来问题在于 DateTime 按钮是可聚焦的。我把它变成不可聚焦的,它按预期工作。当焦点在 RichTextBox 上丢失时,它正在重置插入符号的位置。它只发生了一次,因为在代码中 btn_DateTime 被动态设置为 Focusable = false。我在 XAML 中放置了 Focusable = false 并且从一开始一切都很好。

【问题讨论】:

  • 我真希望我知道该告诉你什么。根据文档,RichTextBox 的 CaretPosition 应该是当前位置,或者如果用户没有移动它/键入任何内容,则应该是 RichTextBox 的开始。
  • 有没有办法从 CaretPosition 中获取 RichTextBox 输入字符串的索引号。就像字符串是 "hellow" 并且 carret 在 he|llow 那么它应该返回 2。

标签: wpf richtextbox


【解决方案1】:

我正在使用此代码成功地执行您正在尝试的操作:

private void insertNowButton_Click(object sender, RoutedEventArgs e)
{
    //NOTE:  The caret position does not change.
    richTextBox1.CaretPosition.InsertTextInRun(DateTime.Now.ToString());
}

编辑:解决更新 1

private void DateTimeStampButton_Click(object sender, RoutedEventArgs e)
{
    var tr = new TextRange(textBox.Document.ContentStart, textBox.Document.ContentEnd);

    if (tr.Text.Length == 2)
    {
        if (tr.Text == "\r\n")
        {
            tr.Text = tr.Text.TrimStart(new[] { '\r', '\n' });
        }
    }

    /* Changing the text is the only way I can get the date to insert at the beginning */
    tr.Text = "I need a beer at ";

    textBox.CaretPosition.InsertTextInRun(DateTime.Now.ToString());
}

看起来SetValue 正在更改文本,因此根据我的测试,实际更改文本会重置插入符号,我同意您的观点,SetValue 导致了问题...

【讨论】:

  • 太棒了!就是这个。我只有一个小问题。如果我输入“hello datetime is”并按下“insert datetime”按钮。然后它显示如下: 02/08/2010 2:27 PM hello datetime is。正如,您可以看到由于某种原因 datetime 是文本的前缀。如果我删除它并将光标设置在 hello datetime 文本的末尾,然后再次按下按钮,那么它工作正常。在我的 RichTextBox 中,我设置了 textBox.CaretPosition = Document.ContentEnd;
  • 在我的简单应用程序(带有一个 RichTextBox、一个 TextBox 和一个 Button 的 WPF)中,它总是将它放在插入符号闪烁的位置。使用另一个窃取插入符号的控件,它将插入插入符号的最后一个位置。我的建议:删除所有对插入符号执行任何操作的代码,然后重试。
  • 感谢您的建议!我浏览了完整的解决方案,但找不到任何其他对插入符号的引用。
  • 我注意到的另一件有趣的事情。如果我输入“hello”,那么插入符号在 o 的末尾,如“hello |”然后我按下它没有在那个位置插入的日期按钮。但是,如果我在同一位置单击鼠标,则它可以正常工作。这个问题有些可疑。
  • @azamsharp:没有发布任何代码,这个 sn-p 是我能给出的最好建议。在我的简单形式中,我可以输入“当前时间是:”(它给出“当前时间是:|”,带有插入符号;按下与上述代码链接的按钮;并得到“当前时间是:2/8 /2010 3:00:57 PM”。您必须发布更多代码以清除任何可疑之处。
【解决方案2】:

我用 WPFToolkit.Extended RichTextBox 尝试了这个解决方案,但它对我不起作用。 但是我找到了另一个,并认为最好将其发布在此处以防其他人使用它。

我的问题还在于,当我单击一个应该在插入符号位置附加文本的按钮后,它反而将其添加到 RichTextBox 的开头。

所以我找到的解决方案与这里的类似 -

RichTextBox CaretPosition physical location

我没有使用 CaretPosition,而是使用 RichTextBox.Selection.Start.InsertTextInRun("SomeText")。

即使没有进行任何选择,它也将选择的开始视为插入符号位置,因此对我来说已经足够了。

我希望有人会觉得这很有用:)

【讨论】:

    【解决方案3】:

    这对我有用:

    private void InsertText(String text, RichTextBox rtb)
    {
        rtb.CaretPosition = rtb.CaretPosition.GetPositionAtOffset(0, LogicalDirection.Forward);
        rtb.CaretPosition.InsertTextInRun(text);
    }
    

    我在这里找到了代码:

    How do I move the caret a certain number of positions in a WPF RichTextBox?

    【讨论】:

      猜你喜欢
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多