Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RichTextBox and Inserting at Caret Positions

Here is the deal: I have a RichTextBox control and it works fine. The problem is that there is a button "Insert Current DateTime" which adds/injects the current datetime into the RichTextBox. The user can enter the datetime anywhere where the caret is pointing. This involves complicated string manipulation and stuff.

Any ideas how to get the current caret position. Whenever I get RichTextBox.CaretPositon it seems it is pointing to the start of the RichTextBox and not where the actual caret is.

UPDATE 1:

The date time button click code:

 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"); 
                }
            }
        }

UPDATE 2:

Turned out the problem was with the DateTime button being Focusable. I turned it to be not focusable and it worked as expected. When focus was lost on the RichTextBox it was resetting the caret position. It happened only once since in the code the btn_DateTime was dynamically being set as Focusable = false. I placed Focusable = false in XAML and everything worked fine from the start.

like image 468
azamsharp Avatar asked Feb 08 '10 19:02

azamsharp


1 Answers

I'm using this code to successfully do what you are attempting:

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

EDIT: Addressing Update 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());
}

It looks like SetValue is changing the text so based on my test that actually changing the text resets the caret, I would agree with you that SetValue is causing the problem...

like image 69
Austin Salonen Avatar answered Sep 28 '22 08:09

Austin Salonen