put some mergefield readonly

4 posts, 0 answers
  1. Grégoire
    Grégoire avatar
    18 posts
    Member since:
    Apr 2011

    Posted 29 Apr 2013 Link to this post

    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.
  2. Boby
    Admin
    Boby avatar
    595 posts

    Posted 02 May 2013 Link to this post

    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.

  3. UI for WPF is Visual Studio 2017 Ready
  4. Grégoire
    Grégoire avatar
    18 posts
    Member since:
    Apr 2011

    Posted 02 May 2013 Link to this post

    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 ?



  5. Petya
    Admin
    Petya avatar
    975 posts

    Posted 07 May 2013 Link to this post

    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.

Back to Top