Consider the following comma separated list that is created dynamically using a merge block:
Pay attention to the last circle where the comma is intentionally missing. In you define the comma as part of the Text ╰ TX Text Control .NET Server for ASP.NET
╰ DocumentServer.Fields Namespace
╰ MergeField Class
╰ TextAfter Property
Gets and sets the text of the field that is displayed after the field's text. property of a Merge ╰ TX Text Control .NET Server for ASP.NET
╰ DocumentServer.Fields Namespace
╰ MergeField Class
The MergeField class implements the MS Word specific MERGEFIELD field. , the comma would be added to the last entry in the merge block as well.
As a result, an unwanted comma is added at the end of the list.
In order to solve that problem, the flexible events of Mail ╰ TX Text Control .NET Server for ASP.NET
╰ DocumentServer Namespace
╰ MailMerge Class
The MailMerge class is a .NET component that can be used to effortlessly merge template documents with database content in .NET projects, such as ASP.NET web applications, web services or Windows services. are used:
- Block
Merging ╰ TX Text Control .NET Server for ASP.NET
╰ DocumentServer Namespace
╰ MailMerge Class
╰ BlockMerging Event
Occurs when a merge block is about to be merged. - Field
Merged ╰ TX Text Control .NET Server for ASP.NET
╰ DocumentServer Namespace
╰ MailMerge Class
╰ FieldMerged Event
Occurs when a field has been merged. - Block
Row Merged ╰ TX Text Control .NET Server for ASP.NET
╰ DocumentServer Namespace
╰ MailMerge Class
╰ BlockRowMerged Event
Occurs when a merge block row has been merged successfully.
For merge blocks, these events are fired in the following order:
To define conditional text after processing, a unique keyword can be defined that is part of the TextAfter property:
The TextBefore property value starts with %REMOVELAST%: followed by the actual string that should be rendered. In our case the comma (",").
When merging the template with data, the above events are attached before calling one of the merge methods:
using (MailMerge mm = new MailMerge()) { | |
mm.TextComponent = textControl1; | |
// attach events | |
mm.BlockMerging += Mm_BlockMerging; | |
mm.FieldMerged += Mm_FieldMerged; | |
mm.BlockRowMerged += Mm_BlockRowMerged; | |
// merge template | |
mm.MergeJsonData(jsonData); | |
} |
The flag bLastBlockRow that indicates that the last row of a block is processed is reset for each new merge block:
bool bLastBlockRow = false; | |
private void Mm_BlockMerging(object sender, MailMerge.BlockMergingEventArgs e) { | |
// reset counter for new block | |
bLastBlockRow = false; | |
} |
bLastBlockRow is updated in the BlockRowMerged event:
private void Mm_BlockRowMerged(object sender, MailMerge.BlockRowMergedEventArgs e) { | |
// before last row gets merged | |
if (e.DataRowNumber == e.DataRowCount - 2) { | |
bLastBlockRow = true; | |
} | |
} |
The actual processing is done in the FieldMerged event. If the field contains the unique keyword and the last row of the merge block is being processed, the complete text after is removed. Otherwise, it is rendered.
private void Mm_FieldMerged(object sender, MailMerge.FieldMergedEventArgs e) { | |
var keyword = "%REMOVELAST%:"; | |
// return if field is outside block | |
if (e.MergeBlockName == "" || e.MailMergeFieldAdapter.TypeName != "MERGEFIELD") | |
return; | |
// convert to the MergeField | |
MergeField field = ((MergeField)e.MailMergeFieldAdapter); | |
// if "text after" contains keyword | |
if (field.TextAfter.StartsWith(keyword)) { | |
if (bLastBlockRow == true) { // remove "text after" when last row | |
field.TextAfter = ""; | |
} | |
else { // else keep "text after" string | |
field.TextAfter = field.TextAfter.Substring( | |
keyword.Length, | |
field.TextAfter.Length - keyword.Length); | |
} | |
} | |
} |