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
3 Answers, 1 is accepted
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.
Iva Toteva
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
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;
}
}
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