Thanks you all for attending this morning’s webinar on how to work with Mail Merge features of the Rich Text Editor. There have been some very good questions and I want to answer some of them in this follow up post. The webinar will also be available on the DevExpress Channel very soon.
First, as promised, here is the source code for the Mailer App that I build during the webinar: Source Code. I have changed things a little bit so that the actual RichEditControl is inside a UserControl (as requested during the webinar). When you do that, make sure to take care of a couple of things:
editor1.RichEdit.BindingContext = dataNavigator1.BindingContext;
IUriStreamProvider
As I explained in the Webinar, adding data fields to the document is very straight forward. Bind to the data source and you’re done (How to: Perform a Mail Merge). We do however need to do some work if we want to bind to a picture.
We use a special field INCLUDEPICTURE to include a picture URI.
{INCLUDEPICTURE "dbimg://{MERGEFIELD EmployeeID}"}
and this is where our IUriStreamProvider comes in. Because we include a URI as an image source, the RichEditControl will try to look it up using the available IUriStreamProvider.
Our implementation looks like this:
public class DBUriStreamProvider : IUriStreamProvider {
static readonly string prefix = "dbimg://";
DataTable table;
string columnName;
public DBUriStreamProvider(DataTable table, string columnName) {
this.table = table;
this.columnName = columnName;
}
public Stream GetStream(string uri) {
uri = uri.Trim();
if (!uri.StartsWith(prefix))
return null;
string strId = uri.Substring(prefix.Length).Trim();
int id;
if (!int.TryParse(strId, out id))
return null;
DataRow row = table.Rows.Find(id);
if (row == null)
return null;
byte[] bytes = row[columnName] as byte[];
if (bytes == null)
return null;
return new MemoryStream(bytes);
}
}
and we register it like so:
IUriStreamService uriService
= (IUriStreamService)richEditControl1.GetService(typeof(IUriStreamService));
if (_provider != null) {
uriService.UnregisterProvider(_provider);
}
if (value != null && value is DataTable) {
_provider = new DBUriStreamProvider((DataTable)value, "Photo");
uriService.RegisterProvider(_provider);
}

Next we'll learn how to properly generate HTML content to be used in emails and how to resolve images during the HTML export.
Cheers
Azret