I use merge field type otherwise you offer and I have two questions about it.
1. How can I redraw field from code then I update any properties in it?
2. How can I make two way binding for field result value (e.g. it calls my function then I change field in editor)?
Thank you.
18 Answers, 1 is accepted
You can update the value after changing some properties of the model by updating the field, for example:
FieldRangeStart firstFieldRangeStart =
this
.radRichTextBox.Document.EnumerateChildrenOfType<FieldRangeStart>().First();
// Change a property:
var firstMergeField = (MergeField)firstFieldRangeStart.Field;
firstMergeField.DateTimeFormatting =
"yyyy-MM"
;
// Update the value:
this
.radRichTextBox.UpdateField(firstFieldRangeStart);
To your second question - mail merge is useful for generating documents by using a document "template", and merge fields evaluated using the records in a data source. That said, it's not meant for two-way binding. Could you elaborate more on what are you trying go achieve, as we may be able to suggest you different approach?
Regards,
Boby
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
Thank you for your answer.
Well, about my project... I'll try.
I have to made a text editor. Besides, some information can be added in text from forms. And this data may be changed in the editor (as text) and in forms (with textboxes e.g.). I think I need two-way binding for that.
May be I must catch field change event, but I don't know how to do it better.
Thank you.
Depending on your requirements, it may turn out that Standalone Reporting Designer could help you. It is a standalone desktop application (it can also be started from your main application), which will allow power users to generate report templates, which can produce documents based on data source. These reports can then be exported to different document formats.
If you decide to stick to RadRichTextBox: I would suggest you to use custom annotations to mark regions in the document, and then manually do synchronizations between the data source and the document - for example on RadRichTextBox.DocumentContentChanged event, iterate over all annotations, get the text in the annotation range and update the data source and the forms. And vise versa - when the text in the form is updated (or the focus is lost), get the particular annotation and update its text.
You can further use protection ranges to protect parts of the document from editing. This is also demonstrated in the Document Protection online demo.
Fields are more useful when the end user should have the ability to modify the evaluation of a range - for example, if a DATE field is added to the document, the end user can go to Code display mode, and add a switch '\@ "d, yyyy"' to modify the date format.
Regards,
Boby
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
By the way, I have a trouble. If I add in a document new field and then in this field add another one, change first field display mode from code to result and back I don't see second field. That's right, there is text fragment from GetResultFragment only but how can I save second field in first for displayed it after?
Maybe my explained isn't clear, but I tried :)
Please, can you create example solution to this way?
To your first question, you can construct nested field using code similar to the following:
DocumentVariableField f1 =
new
DocumentVariableField();
f1.VariableName =
"var1"
;
DocumentVariableField f2 =
new
DocumentVariableField();
f2.SetPropertyValue(DocumentVariableField.VariableNameProperty, f1);
radRichTextBox.InsertField(f2);
To your second question, please find attached a sample project demonstrating the approach. The basic components are:
- Pair of custom annotations - CustomRangeStart, CustomRangeEnd
- UI layer for visualizing the annotation - CustomRangeLayer
- UILayersBuilder for loading the custom layer - CustomUILayersBuilder
Regards,
Boby
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
1. How can I move an element from one layer to another?
2. Can I select the layer for adding the typing text?
3. How many layers can I create for a document without performance reducing?
Yes, sorry for omitting this. The corresponding help artickles are the following:
- Annotations overview
- Custom annotations
- Customize Presentation through UI Layers
To your further questions:
1. and 2. Layers are "volatile" - they visualize elements on each drawing pass. On the next redrawing pass, the elements are cleared and drawn anew. I suppose you are maybe thinking in wrong direction here - could you describe what's your intention behind these questions?
3. It totally depends on the layers itself and how computationally intensive are they. Most layers, however, are redrawn on every layout pass (when you type something in the document, for example), so we should be careful there.
Regards,
Boby
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
Thanks you for your fast answers.
1. and 2. I have to make a variant field. It means that when we select on of the text branch of this field, other must be hided. For example we select a branch in the context menu on this field and it changes own text to text of the branch.
In my project I must hide some elements for inactive branches. Can I somehow ban to draw this boxes on defaults layers?
I am having troubles understanding your requirements. You can subscribe to DocumentContentChanged and update document's mail merge data source accordingly, getting the text from field's ResultFragment.
I would suggest you to try to implement your requirements in sample project, and if you meet specific problems, send it to us attached in a separate support ticket along with their description.
Regards,
Boby
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
Well, I've probably done I need. Maybe later I'll attach my solution in new ticket for others. But I've got some questions about your project (WpfApplication1-2015-01-23-13-34-15Z.zip) if you please.
1. How can I delete CustomAnnotationRange?
2. If there is not a space before left bracket I can't move CustomAnnotationRange to next line. How can I do it?
Thanks.
Hi Alexander,
Annotations can always be deleted from the code-behind using the RadRichTextBox's (or RadDocumentEditor's) DeleteAnnotationRange method.
If you want annotations to be deletable using the Delete and Backspace keys, you can play with the overloads of the DeleteBehavior, BackspaceBehavior and DeleteSelectedBehavior properties of the AnnotationRangeStart and AnnotationRangeEnd, which determine these behaviors.
To your second question - annotations can have position just before or just after them, and this is controlled by SkipPositionBefore property. For example, if you change the CustomRangeStart like this:
public
class
CustomRangeStart : AnnotationRangeStart
{
public
override
bool
SkipPositionBefore
{
get
{
return
false
;
}
}
you will be able to type in text just before the annotation (and not just after it).
Regards, Boby
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
Thank you very much.
One question is about AnnotationRange. I can't attach project for demonstrate that (it allows only .gif, .jpg, .jpeg, .png) but I can explain for your project (WpfApplication1-2015-01-23-13-34-15Z.zip).
I comment this code block in MainWindow constructor:
editor.Insert("Text Before Text Inside Text After");
DocumentPosition rangeStartPosition =
new
DocumentPosition(document);
rangeStartPosition.MoveToNextWordStart();
rangeStartPosition.MoveToNextWordStart();
DocumentPosition rangeEndPosition =
new
DocumentPosition(rangeStartPosition);
rangeEndPosition.MoveToNextWordStart();
rangeEndPosition.MoveToNextWordStart();
document.Selection.SetSelectionStart(rangeStartPosition);
document.Selection.AddSelectionEnd(rangeEndPosition);
and when I try to call InsertAnnotationRange for empty document I have the exception.
But if I insert some text (uncomment first line e.g.) there isn't one.
Is that correct?
Alexander
That's good, thank you. But what about just after it, can I change this behavior too?
To your first question: This method doesn't automatically trigger layout of the document, causing an exception to be thrown. I will log this behavior for revision, but fortunately there is a good workaround - you can just manually invoke the layout in advance:
editor.Document.EnsureDocumentMeasuredAndArranged();
editor.InsertAnnotationRange(new CustomRangeStart(), new CustomRangeEnd());
To your second question - As far as I understand, you want to have position just before and just after the annotation. This is not possible - currently annotation can have position just before or just after it (this is controlled by SkipPositionBefore property) - we designed them in this manner to avoid breaking of the normal user navigation - i.e. as the users move through the document, they won't expect the caret position to stop just before and just after the annotation.
If this is important for you, you can simulate such behavior by adding two consecutive annotation of different types with proper overrides of SkipPositionBefore property.
Regards,
Boby
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.