This is a migrated thread and some comments may be shown as answers.

How to insert text/span into document with custom annotation?

6 Answers 685 Views
RichTextBox
This is a migrated thread and some comments may be shown as answers.
Robert
Top achievements
Rank 1
Robert asked on 02 May 2012, 01:26 AM
Good evening,

How can I insert text into my RadRichTextBox / Document wrapped with custom annotations?

I have the following code, but it only works the first time the code is run. If I run the code a second time by inserted a second piece of text then the annotations aren't wrapped properly.
Please see my code & XAML output below.

Code to insert text and annotation:
//Focus RichTextBox - I have made my own Intellisense ListBox
radRichTextBox.Focus();
//Get Caret position (start position)
DocumentPosition startPosition = new DocumentPosition(radRichTextBox.Document);
//Insert text into document at caret position - text is from Intellisense ListBox selected item
radRichTextBox.Document.Insert(((Products)radListBox.SelectedItem).Name + ": ", radRichTextBox.Document.Style);
//Get caret position now text has been inserted (end position)
DocumentPosition endPosition = new DocumentPosition(this.radRichTextBox.Document);
//Adjust position of Intellisense ListBox to new Caret position
AdjustAutoCompletePosition();
//Reload Intellisense ListBox with new items based on previous selection
SetAutoCompleteListBoxItems(((Products)radListBox.SelectedItem).ID);
//Set Custom Annotation
SemanticRangeEnd rangeEnd = new SemanticRangeEnd();
SemanticRangeStart rangeStart = (SemanticRangeStart)rangeEnd.CreatePairedStart();
rangeStart.Name = "SemanticRange " + count++;
//Place annotation around newly inserted text - note start & end position
radRichTextBox.Document.InsertCustomAnnotationRange(startPosition, endPosition, rangeStart, rangeEnd);

Here is the XAML output when the code is run for the first time (this is correct as it should be):
<t:Paragraph>
  <custom1:SemanticRangeStart AnnotationID="1" Name="SemanticRange 0" />
      <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Appliances: " />
  <custom1:SemanticRangeEnd AnnotationID="1" />
</t:Paragraph>

If I run the code a second time to insert a second piece of text then I get the following output (this isn't what I want):
<t:Paragraph>
  <custom1:SemanticRangeStart AnnotationID="1" Name="SemanticRange 1" />
  <custom1:SemanticRangeEnd AnnotationID="1" />
  <custom1:SemanticRangeStart AnnotationID="2" Name="SemanticRange 0" />
     <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Appliances: " />
  <custom1:SemanticRangeEnd AnnotationID="2" />
 <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Hob: " />
</t:Paragraph>

This is the XAML output that I want to achieve (each piece of inserted text has it's on annotation range):
<t:Paragraph>
 <custom1:SemanticRangeStart AnnotationID="2" Name="SemanticRange 0" />
    <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Appliances: " />     
<custom1:SemanticRangeEnd AnnotationID="2" />
<custom1:SemanticRangeStart AnnotationID="1" Name="SemanticRange 1" />
    <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Hob: " />
<custom1:SemanticRangeEnd AnnotationID="1" /> 
</t:Paragraph>

I think the problem is that I'm not getting the correct start & end positions of the newly inserted text. Please see my c# code "positionStart" & "positionEnd".

Basically my application is an intellisense autocomplete application where the ListBox autcomplete items are drawn from a database. Thus I need the custom annotations to wrap around my text to relate it to the database ID tags. I haven't setup the proper annotation values yet, I'm just playing with the example code from a telerik demo project.

Any advice would be greatly appreciated.

I think I need to achieve the following:
  • Get Caret Position (start position)
  • Insert text into document
  • Get Carent Position (end position)
  • Apply annotation based on start & end positions

 

Thank you for your time,

Rob


************   EDIT   *************

I have tried setting the start and end positions like so but it still doesn't work:

C# Code to insert text & annotations:
//Get caret position (start)
DocumentPosition startPosition = this.radRichTextBox.Document.CaretPosition;
 
//Insert text into document at caret position - text is from Intellisense ListBox selected item
radRichTextBox.Document.Insert(((Products)radListBox.SelectedItem).Name + ": ", radRichTextBox.Document.Style);
 
//Get caret position now text has been inserted (end of text)
DocumentPosition endPosition = this.radRichTextBox.Document.CaretPosition;


XAML Output:
<t:Paragraph>
  <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Appliances: " />
  <custom1:SemanticRangeStart AnnotationID="1" Name="SemanticRange 0" />
  <custom1:SemanticRangeEnd AnnotationID="1" />
    <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Hob: " />
  <custom1:SemanticRangeStart AnnotationID="2" Name="SemanticRange 1" />
  <custom1:SemanticRangeEnd AnnotationID="2" />
    <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Electric: " />
  <custom1:SemanticRangeStart AnnotationID="3" Name="SemanticRange 2" />
  <custom1:SemanticRangeEnd AnnotationID="3" />
    <t:Span FontFamily="Verdana" FontSize="16" FontStyle="Normal" FontWeight="Normal" Text="Beko HIC64102" />
</t:Paragraph>




6 Answers, 1 is accepted

Sort by
0
Robert
Top achievements
Rank 1
answered on 02 May 2012, 03:49 AM
0
Robert
Top achievements
Rank 1
answered on 02 May 2012, 03:56 AM
0
Robert
Top achievements
Rank 1
answered on 02 May 2012, 10:31 AM
Ok this works:

//Insert text into document at caret position - text is Intellisense ListBox selected item
radRichTextBox.Document.Insert(((Products)radListBox.SelectedItem).Name + ": ", radRichTextBox.Document.Style);
DocumentPosition endPosition = new DocumentPosition(this.radRichTextBox.Document.CaretPosition);
DocumentPosition startPosition = new DocumentPosition(endPosition);
startPosition.MoveToCurrentWordStart();
this.radRichTextBox.Document.Selection.SetSelectionStart(startPosition);
this.radRichTextBox.Document.Selection.AddSelectionEnd(endPosition);
string lastWord = this.radRichTextBox.Document.Selection.GetSelectedText();
//Set Custom Annotation
SemanticRangeEnd rangeEnd = new SemanticRangeEnd();
SemanticRangeStart rangeStart = (SemanticRangeStart)rangeEnd.CreatePairedStart();
rangeStart.Name = "SemanticRange " + count++;
//Place annotation around newly inserted text - note start & end position
radRichTextBox.Document.InsertCustomAnnotationRange(startPosition, endPosition, rangeStart, rangeEnd);
this.radRichTextBox.Document.Selection.Clear();


There is one little snag with this. It only selects one word at a time because of the following statement:
startPosition.MoveToCurrentWordStart();

Is there a way to select all text within the current span?

I want to wrap Annotation Tags around a complete span. i.e. <Annotation><Span Text="Hello world!"></Span></Annotation>
0
Robert
Top achievements
Rank 1
answered on 02 May 2012, 11:12 AM
Hi,

I've treid to build the following loop to search back through all of the words in a span.
 However when running I get a null reference Exception error after so many loops.
Any idea why this may be?

DocumentPosition endPosition = new DocumentPosition(this.radRichTextBox.Document.CaretPosition);
DocumentPosition startPosition = new DocumentPosition(endPosition);
startPosition.MoveToCurrentWordStart();
 
while (startPosition.GetCurrentSpanBox().IsStartOfLineSegment != true) ;
{
    startPosition.MoveToPreviousWordStart();
}
0
Accepted
Iva Toteva
Telerik team
answered on 04 May 2012, 06:58 PM
Hello Rob,

As discussed in the support ticket you have opened on the same topic, a whole span can be selected in the following way:

DocumentPosition startPosition = new DocumentPosition(this.editor.Document.CaretPosition);
DocumentPosition endPosition = new DocumentPosition(startPosition);
startPosition.MoveToInline(startPosition.GetPreviousInlineBox().AssociatedInline.FirstLayoutBox as InlineLayoutBox, 0);
   
this.editor.Document.Selection.SetSelectionStart(startPosition);
this.editor.Document.Selection.AddSelectionEnd(endPosition);

In general, if you want to insert some more complex formatted content, you can create a new document with annotations, create a DocumentFragment out of it and insert it in your "main" document. Here is how this can be done:
private void InsertAnnotationFragment()
{
    RadDocument document = new RadDocument();
    Section section = new Section();
    Paragraph paragraph = new Paragraph();
    SemanticRangeStart start = new SemanticRangeStart();
    start.Name = "SemanticRange " + count++;
    SemanticRangeEnd end = new SemanticRangeEnd();
    end.PairWithStart(start);
 
    Span span = new Span("Text that would be inlcuded in the semantic range");
    paragraph.Inlines.Add(start);
    paragraph.Inlines.Add(span);
    paragraph.Inlines.Add(end);
    section.Blocks.Add(paragraph);
    document.Sections.Add(section);
 
    document.MeasureAndArrangeInDefaultSize();
    document.Selection.SelectAll();
 
    this.editor.InsertFragment(document.Selection.CopySelectedDocumentElements());
}

I hope this helps.
Kind regards,
Iva Toteva
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Robert
Top achievements
Rank 1
answered on 04 May 2012, 07:05 PM
Sorry I don't mean to post things twice. I just find that I get a slightly quicker answer from support tickets :).
I suppose it always helps to have the forum post so that other users can benefit from the information.

Thanks again Iva.
Tags
RichTextBox
Asked by
Robert
Top achievements
Rank 1
Answers by
Robert
Top achievements
Rank 1
Iva Toteva
Telerik team
Share this question
or