RichTextBox и вставка в позиции каретки - PullRequest
6 голосов
/ 08 февраля 2010

Вот сделка: у меня есть элемент управления 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. Я поместил Focusable = false в XAML, и с самого начала все работало нормально.

Ответы [ 3 ]

11 голосов
/ 08 февраля 2010

Я использую этот код, чтобы успешно сделать то, что вы пытаетесь:

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 вызывает проблему ...

3 голосов
/ 12 октября 2011

Я попробовал это решение с WPFToolkit.Extended RichTextBox, и оно у меня не сработало. Однако я нашел другой и подумал, что было бы неплохо опубликовать его здесь, если кто-то еще сможет его использовать.

Моя проблема заключалась также в том, что после того, как я нажал кнопку, которая должна добавлять текст в месте расположения каретки, он добавляет его в начале RichTextBox.

Итак, решение, которое я нашел, похоже на приведенное здесь -

RichTextBox CaretPosition физическое местоположение

Вместо использования CaretPosition я использовал RichTextBox.Selection.Start.InsertTextInRun ("SomeText").

Он рассматривал начало выбора как позицию каретки, хотя выбор не был сделан, и поэтому был достаточно хорош для меня.

Я надеюсь, что кто-то найдет это полезным:)

2 голосов
/ 09 октября 2014

Это сработало для меня:

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

Я нашел код здесь:

Как переместить каретку на определенное количество позиций в WPF RichTextBox?

...