MailMerge MergeField FieldProperties not set/reset

4 posts, 0 answers
  1. Wolfgang
    Wolfgang avatar
    3 posts
    Member since:
    Jul 2012

    Posted 26 Jul 2012 Link to this post

    Hi Telerik team,

    We are evaluating your RichTextBox and MailMerge functionality in order to display read-only, mailmerged views.

    In order to create the RadDocument we are using the following sequence:

    RichTextBox.Document = document;
     
    RichTextBox.ChangeAllFieldsDisplayMode(FieldDisplayMode.Result); // first GetResultFragment call
     
    RichTextBox.PreviewFirstMailMergeDataRecord(); // second GetResultFragment call 

     

    The GetResultFragment is called twice during this process.

    On the first call the FieldProperties like PropertyPath, TextAfterIfNotEmpty and TextBeforeIfNotEmpty are set to the values according to our xaml document source.

    On the second call the FieldProperties are null and subsequently the Document is not displayed correct.

    Why are the FieldProperties reset, or is something wrong with the Document initialization process?

     

    Thank you in advance,

    Wolfgang

  2. Iva Toteva
    Admin
    Iva Toteva avatar
    1319 posts

    Posted 27 Jul 2012 Link to this post

    Hi Wolfgang,

    Could you explain in some detail why are you calling both methods, when the two methods generally do the same?

    We may be able to assist you better if you attach your project or a mock-up that includes the custom merge fields functionality. In order to do so, however, you would need to open a support ticket, as only image files are allowed in forums.

    Greetings,
    Iva Toteva
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  3. DevCraft banner
  4. Dhruv
    Dhruv avatar
    1 posts
    Member since:
    Jan 2014

    Posted 02 Jun in reply to Iva Toteva Link to this post

    Even i am facing the same issue.

    I have extended MergeField class to create my custom merge field class with multiple properties which i can preserve in xaml file whiel exporting.

     

    My GetResultFragment is called twice and in second call the custom property DateFormat is null so finally my resulted value is displayed wrong in editor.

     

    public class CustomDateField : MergeField
        {
            private const string CustomFieldName = "CustomDateField";
            
            static CustomDateField()
            {
                CodeBasedFieldFactory.RegisterFieldType(CustomDateField.CustomFieldName, () => { return new CustomDateField(); });
            }

            [XamlSerializable]
            public string DateFormat { get; set; }

            public override Field CreateInstance()
            {
                return new CustomDateField();
            }

            public override string FieldTypeName
            {
                get
                {
                    return CustomDateField.CustomFieldName;
                }
            }

            public override void CopyPropertiesFrom(Field fromField)
            {
                CustomDateField mergeField = fromField as CustomDateField;
                if (mergeField != null)
                {
                    this.DateFormat = mergeField.DateFormat;
                }
                base.CopyPropertiesFrom(fromField);
            }

            protected override DocumentFragment GetResultFragment()
            {
                try
                {
                    var data = this.Document.MailMergeDataSource.CurrentItem as IDictionary<string, Object>;
                    if (data == null)
                    {
                        return null;
                    }
                    else
                    {
                        object outputvalue = null;
                        data.TryGetValue(this.PropertyPath, out outputvalue);
                        if (outputvalue != null)
                        {
                            string date = Convert.ToDateTime(outputvalue).ToString(this.DateFormat);
                            RadDocument document = new RadDocument();
                            Section section = new Section();
                            Paragraph paragraph = new Paragraph();
                            Span span = new Span(date);
                            paragraph.Inlines.Add(span);
                            section.Blocks.Add(paragraph);
                            document.Sections.Add(section);
                            return new DocumentFragment(document);
                        }
                    }
                }
                catch (Exception ex)
                {

                }

                return null;
            }
        }

  5. Boyko
    Admin
    Boyko avatar
    17 posts

    Posted 06 Jun Link to this post

    Hi Dhruv,

    You need to modify the CustomDateField class in order to support a custom property. What needs to be done is adding a switch and an override to the BuildCodeOverride() method where the custom property should be mapped to the switch. For your convenience, I have modified your code:
        
    public class CustomDateField : MergeField
    {
        private const string CustomFieldName = "CustomDateField";
     
        private static readonly string DateFormatSwitch = @"\df"; // unique for the entire set of mail merge field switches.
     
        private readonly FieldProperty dateFormat;
     
        public static readonly FieldPropertyDefinition DateFormatDefinition = new FieldPropertyDefinition("DateFormat");
     
        static CustomDateField()
        {
            CodeBasedFieldFactory.RegisterFieldType(CustomDateField.CustomFieldName, () => { return new CustomDateField(); });
        }
     
        public CustomDateField()
        {
            this.dateFormat = new FieldProperty(this, CustomDateField.DateFormatDefinition);
        }
     
        [XamlSerializable]
        public string DateFormat
        {
            get
            {
                return this.dateFormat.GetValue();
            }
            set
            {
                if (!this.dateFormat.IsNestedField && this.dateFormat.GetValue() == value)
                {
                    return;
                }
     
                this.dateFormat.SetValue(value);
                this.InvalidateCode();
            }
        }
         
        public override Field CreateInstance()
        {
            return new CustomDateField();
        }
     
        public override string FieldTypeName
        {
            get
            {
                return CustomDateField.CustomFieldName;
            }
        }
     
        public override void CopyPropertiesFrom(Field fromField)
        {
            CustomDateField mergeField = fromField as CustomDateField;
            if (mergeField != null)
            {
                this.DateFormat = mergeField.DateFormat;
            }
     
            base.CopyPropertiesFrom(fromField);
        }
     
        protected override void BuildCodeOverride()
        {
            base.BuildCodeOverride();
     
            this.CodeBuilder.AddSwitch(CustomDateField.DateFormatSwitch, this.dateFormat);
        }
     
        protected override void CopyPropertiesFromCodeExpression(FieldCodeExpression fieldCodeExpression)
        {
            base.CopyPropertiesFromCodeExpression(fieldCodeExpression);
            FieldSwitchNode fieldSwitchNode = fieldCodeExpression.GetFieldSwitch(DateFormatSwitch);
            this.dateFormat.SetValue(fieldSwitchNode.FieldArgumentNode);
        }
     
        protected override DocumentFragment GetResultFragment()
        {           
            try
            {
                var data = this.Document.MailMergeDataSource.CurrentItem as IDictionary<string, Object>;
                if (data == null)
                {
                    //return null; //This return value is not allowed. It may crash the application.
                    return new DocumentFragment(new RadDocument());
                }
                else
                {
                    object outputvalue = data;
                    data.TryGetValue(this.PropertyPath, out outputvalue);
                    if (outputvalue != null)
                    {
                        string date = Convert.ToDateTime(outputvalue).ToString(this.DateFormat);
                        RadDocument document = new RadDocument();
                        Section section = new Section();
                        Paragraph paragraph = new Paragraph();
                        Span span = new Span(date);
                        paragraph.Inlines.Add(span);
                        section.Blocks.Add(paragraph);
                        document.Sections.Add(section);
                        return new DocumentFragment(document);
                    }
                }
            }
            catch (Exception ex)
            {
     
            }
     
            //return null; //This return value is not allowed. It may crash the application.
            return new DocumentFragment(new RadDocument());
        }
    }

    If you need more information how to create a custom field, please read our Custom Field help article.
     
    Regards,
    Boyko
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Back to Top