2

I want to allow users to select from a list of predefined templates. When a template is selected, the RichEditControl (REC) displays a document formatted according to the selected template, with fields already merged. (The user never sees the double-bracket "code-behind" of the merge document.) My templates are in a database as varbinary and passed up to the gui as byte arrays in a class that, stripped down, looks like this:

public class Template
{
  public byte[] Document {get;set;}
}

In the form that contains the REC, I'm calling the following method in the event handler for the changed event of the drop-down that contains the available templates (the letterWriterEditor is my REC, and the templateBindingSource is bound to the LetterWriterMergeFieldCollection, a class containing string properties representing the fields I'd like to have the option of merging in the document, along with their values for this particular letter (determined elsewhere in the program)):

 public void MergeTemplateFieldsWithValues(IList<LetterWriterMergeFieldCollection> mergeValues, Template template)
    {
        using (Stream s = new MemoryStream(template.Document))
        {
            letterWriterEditor.LoadDocument(s, DocumentFormat.Rtf);
        }

        BindingList<LetterWriterMergeFieldCollection> bindingList = new BindingList<LetterWriterMergeFieldCollection>(mergeValues);
        templateBindingSource.DataSource = bindingList;
        templateBindingSource.ResetBindings(false);
    }

I have the following statement in this form's constructor:

 letterWriterEditor.Options.MailMerge.ViewMergedData = true;

The merge fields are bound fine: I can insert them manually using one of the Mailings buttons in the REC's ribbon bar. But the document ends up blank when I attempt to do it programmatically. I'd like it to end up as a merged letter ready for saving as soon as the user selects the desired template. My understanding is that, with the ViewMergeData property set to true, this is what should be happening.

If anyone has any ideas, I'd be grateful. Thanks in advance.

4

1 回答 1

3

I'm currently doing something similar, in my case I load the template inside a RichEditDocumentServer (which is like a RichEditControl but with no UI) then set the DataSource of MailMerge, after that just call the RichEditDocumentServer's MailMerge method and give the RichEditControl's document as parameter.

RichEditDocumentServer loads the template and does the MailMerge then displays the document in the RichEditControl of the Form.

You can try this:

Declare a RichEditDocumentServer in your Form.

RichEditDocumentServer docServer;

And initialize it in your form contructor or OnLoad.

docServer = New RichEditDocumentServer();

Then just change your method like this:

public void MergeTemplateFieldsWithValues(IList<LetterWriterMergeFieldCollection> mergeValues, Template template)
    {
        using (Stream s = new MemoryStream(template.Document))
        {
        docServer.LoadDocument(s, DocumentFormat.Rtf);
    }

    BindingList<LetterWriterMergeFieldCollection> bindingList = new BindingList<LetterWriterMergeFieldCollection>(mergeValues);
    templateBindingSource.DataSource = bindingList;
    templateBindingSource.ResetBindings(false);
}

I'm not sure where did you Bind your Fields to the document but I think templateBindingSource does it so just have to set the DataSource of docServer:

docServer.DataSource = templateBindingSource;

after that just do the MailMerge and display it using your form letterWriterEditor:

docServer.MailMerge(letterWriterEditor.Document);

It should work. :)

于 2012-09-10T19:18:33.030 回答