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

put some mergefield readonly

3 Answers 126 Views
RichTextBox
This is a migrated thread and some comments may be shown as answers.
Grégoire
Top achievements
Rank 1
Grégoire asked on 29 Apr 2013, 11:48 AM
Hi,
I want to "protect" mergefield inside my document, to prevent user to change the display of the field directly in the richtextbox(i use a specific editor to edit the value of my mergefield).

I tried to write a procedure to put or remove readonly on my mergefield, but I have some trouble to make it work :

private void SetMergeFieldReadOnly(MergeField field, RadRichTextBox richTextBox, bool isReadonly)
        {
            var fieldEnd = richTextBox.Document.EnumerateChildrenOfType<FieldRangeEnd>()
                .FirstOrDefault(fs => (fs.FieldRangeStart.Field is MergeField)
                                   && (((MergeField)fs.FieldRangeStart.Field).PropertyPath == field.PropertyPath));
            if (fieldEnd != null)
            {
                var fieldStart = fieldEnd.FieldRangeStart;
                var posFieldStart = new DocumentPosition(richTextBox.Document);
                var posFieldEnd = new DocumentPosition(richTextBox.Document);
                posFieldStart.MoveToInline(fieldStart);
                posFieldEnd.MoveToInline(fieldEnd);
                if (isReadonly) // add readonlyrange
                {
                    richTextBox.Document.Selection.Clear();
                    richTextBox.Document.Selection.SetSelectionStart(posFieldStart);
                    richTextBox.Document.Selection.AddSelectionEnd(posFieldEnd);
                    richTextBox.InsertReadOnlyRange();
                }
                else // remove readonlyrange
                {
                    // 1st method - doesn't work.
                    //richTextBox.Document.Selection.Clear();
                    //richTextBox.Document.Selection.SetSelectionStart(posDebField);
                    //richTextBox.Document.Selection.AddSelectionEnd(posFinField);
                    //richTextBox.DeleteReadOnlyRange();  // <-- no error but the field is still readonly after that.
 
                    // 2nd method - works but not properly
                    var readOnlyRangeStarts = richTextBox.Document.EnumerateChildrenOfType<ReadOnlyRangeStart>();
                    var posDebReadOnly = new DocumentPosition(richTextBox.Document);
                    var posFinReadOnly = new DocumentPosition(richTextBox.Document);
                    foreach (var readOnlyRangeStart in readOnlyRangeStarts)
                    {
                        if (readOnlyRangeStart.End != null)
                        {
                            posDebReadOnly.MoveToInline(readOnlyRangeStart);
                            posFinReadOnly.MoveToInline(readOnlyRangeStart.End);
                            if ((posFinReadOnly >= posFieldStart) && (posDebReadOnly <= posFieldEnd))
                            {
                                richTextBox.DeleteReadOnlyRange(readOnlyRangeStart);   // remove the protection on ALL the readonly range !!!
                            }
                        }
                    }
                }
            }
        }


I wonder if there are not some easier way to do this ? (Or I might be doing something wrong ?)

At the moment, I can only set/unset readonly ALL the mergefield of the document. It works, but sadly it's really slow ...

Are they're some way to "lock" the fields without using some ReadOnlyRange ?

Thanks.

3 Answers, 1 is accepted

Sort by
0
Boby
Telerik team
answered on 02 May 2013, 07:20 AM
Hello Grégoire,

Thank you for writing.

There isn't a built-in way to protect merge fields from editing. RichTextBox.DeleteReadOnlyRange works with the current caret position (or the beginning of the selection if there is one), while RichTextBox.DeleteReadOnlyRange(ReadOnlyRangeStart) deletes the range by passed range start. Unfortunately, the first overload doesn't work in case of nested annotations. You can use your former method by utilizing the second overload to remove the protection from the current merge field. Here is a sample snippet:
var currentRange = this.radRichTextBox.Document
    .GetContainingAnnotationRanges<ReadOnlyRangeStart>(this.radRichTextBox.Document.CaretPosition.GetCurrentInline(), true)
    .FirstOrDefault();
 
if (currentRange != null)
{
    this.radRichTextBox.DeleteReadOnlyRange(currentRange);               
}

You can also easily create a selection around the current field using DocumentSelection.SelectAnnotationRange method:
var currentRange = this.radRichTextBox.Document
    .GetContainingAnnotationRanges<FieldRangeStartBase>(this.radRichTextBox.Document.CaretPosition.GetCurrentInline(), true)
        .FirstOrDefault();
this.radRichTextBox.Document.Selection.SelectAnnotationRange(currentRange);
this.radRichTextBox.InsertReadOnlyRange();

I hope this helps.

Regards,
Boby
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Grégoire
Top achievements
Rank 1
answered on 02 May 2013, 03:06 PM
Thank for the answer.

I have tried your solution, but i still have the same problem : the DeleteReadOnlyRange(currentRange) remove the readonly protection on ALL the MergeField in the document, and not just on the currentRange selection.

Is it a bug or does it supposed to word this way ?



0
Petya
Telerik team
answered on 07 May 2013, 11:25 AM
Hello Grégoire,

Please make sure that the method is only called once in your application. We are unaware of any issues in this regard and I am unable to reproduce the behavior you are observing.

If you are unable to pinpoint the source of the problem on your side, please open a support ticket and attach a sample that can help us replicate the issue.

Let us know how it goes. 

Regards,
Petya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
RichTextBox
Asked by
Grégoire
Top achievements
Rank 1
Answers by
Boby
Telerik team
Grégoire
Top achievements
Rank 1
Petya
Telerik team
Share this question
or